summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2021-02-01 13:49:33 +0100
committerSergei Golubchik <serg@mariadb.org>2021-02-01 13:49:33 +0100
commit60ea09eae6f464e8ec483f4d31f7b910a8451c28 (patch)
tree7b79f55a96c8bc9dc3f0353cc08f43b825fe8707 /sql
parent59eda73eff1a22ac0373d818bc802c05e82b5449 (diff)
parentff5186fd2b1ed06ed40fe3d817b41326e3f943d5 (diff)
downloadmariadb-git-60ea09eae6f464e8ec483f4d31f7b910a8451c28.tar.gz
Merge branch '10.2' into 10.3
Diffstat (limited to 'sql')
-rw-r--r--sql/create_options.cc5
-rw-r--r--sql/handler.cc3
-rw-r--r--sql/handler.h2
-rw-r--r--sql/item.cc16
-rw-r--r--sql/item.h19
-rw-r--r--sql/item_cmpfunc.cc6
-rw-r--r--sql/mdl.cc8
-rw-r--r--sql/mysqld.cc44
-rw-r--r--sql/mysqld.h4
-rw-r--r--sql/opt_range.cc1
-rw-r--r--sql/rpl_parallel.cc5
-rw-r--r--sql/rpl_rli.cc4
-rw-r--r--sql/slave.cc223
-rw-r--r--sql/spatial.cc1
-rw-r--r--sql/sql_acl.cc6
-rw-r--r--sql/sql_class.cc51
-rw-r--r--sql/sql_class.h18
-rw-r--r--sql/sql_connect.cc2
-rw-r--r--sql/sql_lex.cc3
-rw-r--r--sql/sql_manager.cc87
-rw-r--r--sql/sql_manager.h2
-rw-r--r--sql/sql_parse.cc1
-rw-r--r--sql/sql_plugin.h9
-rw-r--r--sql/sql_prepare.cc11
-rw-r--r--sql/sql_repl.cc17
-rw-r--r--sql/sql_repl.h1
-rw-r--r--sql/sql_show.cc33
-rw-r--r--sql/sql_statistics.cc4
-rw-r--r--sql/sql_table.cc13
-rw-r--r--sql/sql_test.cc1
-rw-r--r--sql/sql_update.cc3
-rw-r--r--sql/sql_yacc.yy68
-rw-r--r--sql/unireg.cc3
-rw-r--r--sql/upgrade_conf_file.cc1
-rw-r--r--sql/wsrep_sst.cc6
-rw-r--r--sql/wsrep_thd.cc14
36 files changed, 350 insertions, 345 deletions
diff --git a/sql/create_options.cc b/sql/create_options.cc
index a8d997efaf4..066adcd92e3 100644
--- a/sql/create_options.cc
+++ b/sql/create_options.cc
@@ -98,14 +98,13 @@ static bool report_unknown_option(THD *thd, engine_option_value *val,
{
DBUG_ENTER("report_unknown_option");
- if (val->parsed || suppress_warning)
+ if (val->parsed || suppress_warning || thd->slave_thread)
{
DBUG_PRINT("info", ("parsed => exiting"));
DBUG_RETURN(FALSE);
}
- if (!(thd->variables.sql_mode & MODE_IGNORE_BAD_TABLE_OPTIONS) &&
- !thd->slave_thread)
+ if (!(thd->variables.sql_mode & MODE_IGNORE_BAD_TABLE_OPTIONS))
{
my_error(ER_UNKNOWN_OPTION, MYF(0), val->name.str);
DBUG_RETURN(TRUE);
diff --git a/sql/handler.cc b/sql/handler.cc
index 6792e80b8fe..79dcee037a5 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -835,9 +835,11 @@ static my_bool kill_handlerton(THD *thd, plugin_ref plugin,
{
handlerton *hton= plugin_hton(plugin);
+ mysql_mutex_lock(&thd->LOCK_thd_data);
if (hton->state == SHOW_OPTION_YES && hton->kill_query &&
thd_get_ha_data(thd, hton))
hton->kill_query(hton, thd, *(enum thd_kill_levels *) level);
+ mysql_mutex_unlock(&thd->LOCK_thd_data);
return FALSE;
}
@@ -5163,6 +5165,7 @@ int ha_create_table(THD *thd, const char *path,
char name_buff[FN_REFLEN];
const char *name;
TABLE_SHARE share;
+ Abort_on_warning_instant_set old_abort_on_warning(thd, 0);
bool temp_table __attribute__((unused)) =
create_info->options & (HA_LEX_CREATE_TMP_TABLE | HA_CREATE_TMP_ALTER);
DBUG_ENTER("ha_create_table");
diff --git a/sql/handler.h b/sql/handler.h
index 2a346e8d9d1..49fef4a5cc9 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1474,7 +1474,7 @@ struct handlerton
enum handler_create_iterator_result
(*create_iterator)(handlerton *hton, enum handler_iterator_type type,
struct handler_iterator *fill_this_in);
- int (*abort_transaction)(handlerton *hton, THD *bf_thd,
+ void (*abort_transaction)(handlerton *hton, THD *bf_thd,
THD *victim_thd, my_bool signal);
int (*set_checkpoint)(handlerton *hton, const XID* xid);
int (*get_checkpoint)(handlerton *hton, XID* xid);
diff --git a/sql/item.cc b/sql/item.cc
index cd81aca7e37..aae151deac9 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -8559,6 +8559,22 @@ bool Item_direct_ref::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
}
+longlong Item_direct_ref::val_time_packed()
+{
+ longlong tmp = (*ref)->val_time_packed();
+ null_value= (*ref)->null_value;
+ return tmp;
+}
+
+
+longlong Item_direct_ref::val_datetime_packed()
+{
+ longlong tmp = (*ref)->val_datetime_packed();
+ null_value= (*ref)->null_value;
+ return tmp;
+}
+
+
Item_cache_wrapper::~Item_cache_wrapper()
{
DBUG_ASSERT(expr_cache == 0);
diff --git a/sql/item.h b/sql/item.h
index f161b55e950..9200dd80ee8 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -5102,13 +5102,16 @@ public:
return Item_ref::fix_fields(thd, it);
}
void save_val(Field *to);
+ /* Below we should have all val() methods as in Item_ref */
double val_real();
longlong val_int();
- String *val_str(String* tmp);
my_decimal *val_decimal(my_decimal *);
bool val_bool();
+ String *val_str(String* tmp);
bool is_null();
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ longlong val_datetime_packed();
+ longlong val_time_packed();
virtual Ref_Type ref_type() { return DIRECT_REF; }
Item *get_copy(THD *thd)
{ return get_item_copy<Item_direct_ref>(thd, this); }
@@ -5423,6 +5426,20 @@ public:
}
return Item_direct_ref::get_date(ltime, fuzzydate);
}
+ longlong val_time_packed()
+ {
+ if (check_null_ref())
+ return 0;
+ else
+ return Item_direct_ref::val_time_packed();
+ }
+ longlong val_datetime_packed()
+ {
+ if (check_null_ref())
+ return 0;
+ else
+ return Item_direct_ref::val_datetime_packed();
+ }
bool send(Protocol *protocol, st_value *buffer);
void save_org_in_field(Field *field,
fast_field_copier data __attribute__ ((__unused__)))
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index ebb1c480abb..d5a4e644748 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1177,9 +1177,9 @@ longlong Item_func_truth::val_int()
bool Item_in_optimizer::is_top_level_item()
{
- if (invisible_mode())
- return FALSE;
- return ((Item_in_subselect *)args[1])->is_top_level_item();
+ if (!invisible_mode())
+ return ((Item_in_subselect *)args[1])->is_top_level_item();
+ return false;
}
diff --git a/sql/mdl.cc b/sql/mdl.cc
index 952648ce2d8..a53a1f08c2c 100644
--- a/sql/mdl.cc
+++ b/sql/mdl.cc
@@ -1084,7 +1084,7 @@ MDL_wait::timed_wait(MDL_context_owner *owner, struct timespec *abs_timeout,
DBUG_ASSERT(!debug_sync_set_action((owner->get_thd()),
STRING_WITH_LEN(act)));
};);
- if (wsrep_thd_is_BF(owner->get_thd(), false))
+ if (WSREP_ON && wsrep_thd_is_BF(owner->get_thd(), false))
{
wait_result= mysql_cond_wait(&m_COND_wait_status, &m_LOCK_wait_status);
}
@@ -1157,7 +1157,7 @@ void MDL_lock::Ticket_list::add_ticket(MDL_ticket *ticket)
*/
DBUG_ASSERT(ticket->get_lock());
#ifdef WITH_WSREP
- if ((this == &(ticket->get_lock()->m_waiting)) &&
+ if (WSREP_ON && (this == &(ticket->get_lock()->m_waiting)) &&
wsrep_thd_is_BF(ticket->get_ctx()->get_thd(), false))
{
Ticket_iterator itw(ticket->get_lock()->m_waiting);
@@ -1583,7 +1583,7 @@ MDL_lock::can_grant_lock(enum_mdl_type type_arg,
ticket->is_incompatible_when_granted(type_arg))
{
#ifdef WITH_WSREP
- if (wsrep_thd_is_BF(requestor_ctx->get_thd(),false) &&
+ if (WSREP_ON && wsrep_thd_is_BF(requestor_ctx->get_thd(),false) &&
key.mdl_namespace() == MDL_key::GLOBAL)
{
WSREP_DEBUG("global lock granted for BF: %lu %s",
@@ -1617,7 +1617,7 @@ MDL_lock::can_grant_lock(enum_mdl_type type_arg,
}
else
{
- if (wsrep_thd_is_BF(requestor_ctx->get_thd(), false) &&
+ if (WSREP_ON && wsrep_thd_is_BF(requestor_ctx->get_thd(), false) &&
key.mdl_namespace() == MDL_key::GLOBAL)
{
WSREP_DEBUG("global lock granted for BF (waiting queue): %lu %s",
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index d037cce0fed..4edd47d32bf 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -373,7 +373,6 @@ static bool binlog_format_used= false;
LEX_STRING opt_init_connect, opt_init_slave;
mysql_cond_t COND_thread_cache;
static mysql_cond_t COND_flush_thread_cache;
-mysql_cond_t COND_slave_background;
static DYNAMIC_ARRAY all_options;
static longlong start_memory_used;
@@ -750,7 +749,7 @@ mysql_mutex_t
LOCK_crypt,
LOCK_global_system_variables,
LOCK_user_conn, LOCK_slave_list,
- LOCK_connection_count, LOCK_error_messages, LOCK_slave_background;
+ LOCK_connection_count, LOCK_error_messages;
mysql_mutex_t LOCK_stats, LOCK_global_user_client_stats,
LOCK_global_table_stats, LOCK_global_index_stats;
@@ -942,8 +941,7 @@ PSI_mutex_key key_LOCK_stats,
PSI_mutex_key key_LOCK_gtid_waiting;
PSI_mutex_key key_LOCK_after_binlog_sync;
-PSI_mutex_key key_LOCK_prepare_ordered, key_LOCK_commit_ordered,
- key_LOCK_slave_background;
+PSI_mutex_key key_LOCK_prepare_ordered, key_LOCK_commit_ordered;
PSI_mutex_key key_TABLE_SHARE_LOCK_share;
PSI_mutex_key key_LOCK_ack_receiver;
@@ -1018,7 +1016,6 @@ static PSI_mutex_info all_server_mutexes[]=
{ &key_LOCK_prepare_ordered, "LOCK_prepare_ordered", PSI_FLAG_GLOBAL},
{ &key_LOCK_after_binlog_sync, "LOCK_after_binlog_sync", PSI_FLAG_GLOBAL},
{ &key_LOCK_commit_ordered, "LOCK_commit_ordered", PSI_FLAG_GLOBAL},
- { &key_LOCK_slave_background, "LOCK_slave_background", PSI_FLAG_GLOBAL},
{ &key_LOG_INFO_lock, "LOG_INFO::lock", 0},
{ &key_LOCK_thread_count, "LOCK_thread_count", PSI_FLAG_GLOBAL},
{ &key_LOCK_thread_cache, "LOCK_thread_cache", PSI_FLAG_GLOBAL},
@@ -1085,7 +1082,7 @@ PSI_cond_key key_TC_LOG_MMAP_COND_queue_busy;
PSI_cond_key key_COND_rpl_thread_queue, key_COND_rpl_thread,
key_COND_rpl_thread_stop, key_COND_rpl_thread_pool,
key_COND_parallel_entry, key_COND_group_commit_orderer,
- key_COND_prepare_ordered, key_COND_slave_background;
+ key_COND_prepare_ordered;
PSI_cond_key key_COND_wait_gtid, key_COND_gtid_ignore_duplicates;
PSI_cond_key key_COND_ack_receiver;
@@ -1137,7 +1134,6 @@ static PSI_cond_info all_server_conds[]=
{ &key_COND_parallel_entry, "COND_parallel_entry", 0},
{ &key_COND_group_commit_orderer, "COND_group_commit_orderer", 0},
{ &key_COND_prepare_ordered, "COND_prepare_ordered", 0},
- { &key_COND_slave_background, "COND_slave_background", 0},
{ &key_COND_start_thread, "COND_start_thread", PSI_FLAG_GLOBAL},
{ &key_COND_wait_gtid, "COND_wait_gtid", 0},
{ &key_COND_gtid_ignore_duplicates, "COND_gtid_ignore_duplicates", 0},
@@ -2032,8 +2028,11 @@ static void __cdecl kill_server(int sig_ptr)
close_connections();
+#ifdef WITH_WSREP
if (wsrep_inited == 1)
wsrep_deinit(true);
+ wsrep_sst_auth_free();
+#endif /* WITH_WSREP */
if (sig != MYSQL_KILL_SIGNAL &&
sig != 0)
@@ -2153,6 +2152,7 @@ extern "C" void unireg_abort(int exit_code)
/* In bootstrap mode we deinitialize wsrep here. */
if (opt_bootstrap && wsrep_inited)
wsrep_deinit(true);
+ wsrep_sst_auth_free();
}
#endif // WITH_WSREP
@@ -2400,8 +2400,6 @@ static void clean_up_mutexes()
mysql_cond_destroy(&COND_prepare_ordered);
mysql_mutex_destroy(&LOCK_after_binlog_sync);
mysql_mutex_destroy(&LOCK_commit_ordered);
- mysql_mutex_destroy(&LOCK_slave_background);
- mysql_cond_destroy(&COND_slave_background);
DBUG_VOID_RETURN;
}
@@ -4899,9 +4897,6 @@ static int init_thread_environment()
MY_MUTEX_INIT_SLOW);
mysql_mutex_init(key_LOCK_commit_ordered, &LOCK_commit_ordered,
MY_MUTEX_INIT_SLOW);
- mysql_mutex_init(key_LOCK_slave_background, &LOCK_slave_background,
- MY_MUTEX_INIT_SLOW);
- mysql_cond_init(key_COND_slave_background, &COND_slave_background, NULL);
#ifdef HAVE_OPENSSL
mysql_mutex_init(key_LOCK_des_key_file,
@@ -5509,6 +5504,10 @@ static int init_server_components()
that there are unprocessed options.
*/
my_getopt_skip_unknown= 0;
+#ifdef WITH_WSREP
+ if (wsrep_recovery)
+ my_getopt_skip_unknown= TRUE;
+#endif
if ((ho_error= handle_options(&remaining_argc, &remaining_argv, no_opts,
mysqld_get_one_option)))
@@ -5518,20 +5517,27 @@ static int init_server_components()
remaining_argv--;
my_getopt_skip_unknown= TRUE;
- if (remaining_argc > 1)
+#ifdef WITH_WSREP
+ if (!wsrep_recovery)
{
- fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n",
- my_progname, remaining_argv[1]);
- unireg_abort(1);
+#endif
+ if (remaining_argc > 1)
+ {
+ fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n",
+ my_progname, remaining_argv[1]);
+ unireg_abort(1);
+ }
+#ifdef WITH_WSREP
}
+#endif
}
- if (init_io_cache_encryption())
- unireg_abort(1);
-
if (opt_abort)
unireg_abort(0);
+ if (init_io_cache_encryption())
+ unireg_abort(1);
+
/* if the errmsg.sys is not loaded, terminate to maintain behaviour */
if (!DEFAULT_ERRMSGS[0][0])
unireg_abort(1);
diff --git a/sql/mysqld.h b/sql/mysqld.h
index dc0641502ce..47f19b76c93 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -615,8 +615,7 @@ extern mysql_mutex_t
LOCK_error_log, LOCK_delayed_insert, LOCK_short_uuid_generator,
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_user_conn,
- LOCK_prepared_stmt_count, LOCK_error_messages, LOCK_connection_count,
- LOCK_slave_background;
+ LOCK_prepared_stmt_count, LOCK_error_messages, LOCK_connection_count;
extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_thread_count,
LOCK_global_system_variables;
extern mysql_mutex_t LOCK_start_thread;
@@ -630,7 +629,6 @@ extern mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
extern mysql_prlock_t LOCK_system_variables_hash;
extern mysql_cond_t COND_thread_count, COND_start_thread;
extern mysql_cond_t COND_manager;
-extern mysql_cond_t COND_slave_background;
extern int32 thread_count, service_thread_count;
extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher,
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 30c74799b6f..8f8767c10b3 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -10425,6 +10425,7 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only,
uint keynr= param->real_keynr[idx];
DBUG_ENTER("check_quick_select");
+ param->is_ror_scan= FALSE;
/* Handle cases when we don't have a valid non-empty list of range */
if (!tree)
DBUG_RETURN(HA_POS_ERROR);
diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc
index eb0bdbcf868..7ebb609dc58 100644
--- a/sql/rpl_parallel.cc
+++ b/sql/rpl_parallel.cc
@@ -4,6 +4,7 @@
#include "rpl_mi.h"
#include "sql_parse.h"
#include "debug_sync.h"
+#include "sql_repl.h"
/*
Code for optional parallel execution of replicated events on the slave.
@@ -82,7 +83,7 @@ handle_queued_pos_update(THD *thd, rpl_parallel_thread::queued_event *qev)
return;
mysql_mutex_lock(&rli->data_lock);
- cmp= strcmp(rli->group_relay_log_name, qev->event_relay_log_name);
+ cmp= compare_log_name(rli->group_relay_log_name, qev->event_relay_log_name);
if (cmp < 0)
{
rli->group_relay_log_pos= qev->future_event_relay_log_pos;
@@ -91,7 +92,7 @@ handle_queued_pos_update(THD *thd, rpl_parallel_thread::queued_event *qev)
rli->group_relay_log_pos < qev->future_event_relay_log_pos)
rli->group_relay_log_pos= qev->future_event_relay_log_pos;
- cmp= strcmp(rli->group_master_log_name, qev->future_event_master_log_name);
+ cmp= compare_log_name(rli->group_master_log_name, qev->future_event_master_log_name);
if (cmp < 0)
{
strcpy(rli->group_master_log_name, qev->future_event_master_log_name);
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 2218dfc76c2..58594f6f645 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -993,7 +993,7 @@ void Relay_log_info::inc_group_relay_log_pos(ulonglong log_pos,
if (rgi->is_parallel_exec)
{
/* In case of parallel replication, do not update the position backwards. */
- int cmp= strcmp(group_relay_log_name, rgi->event_relay_log_name);
+ int cmp= compare_log_name(group_relay_log_name, rgi->event_relay_log_name);
if (cmp < 0)
{
group_relay_log_pos= rgi->future_event_relay_log_pos;
@@ -1005,7 +1005,7 @@ void Relay_log_info::inc_group_relay_log_pos(ulonglong log_pos,
In the parallel case we need to update the master_log_name here, rather
than in Rotate_log_event::do_update_pos().
*/
- cmp= strcmp(group_master_log_name, rgi->future_event_master_log_name);
+ cmp= compare_log_name(group_master_log_name, rgi->future_event_master_log_name);
if (cmp <= 0)
{
if (cmp < 0)
diff --git a/sql/slave.cc b/sql/slave.cc
index 28e08e32346..f145d644bb7 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -61,6 +61,7 @@
#include "rpl_parallel.h"
#include "sql_show.h"
#include "semisync_slave.h"
+#include "sql_manager.h"
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
@@ -360,9 +361,9 @@ end:
}
-static void
-handle_gtid_pos_auto_create_request(THD *thd, void *hton)
+static void bg_gtid_pos_auto_create(void *hton)
{
+ THD *thd= NULL;
int UNINIT_VAR(err);
plugin_ref engine= NULL, *auto_engines;
rpl_slave_state::gtid_pos_table *entry;
@@ -374,7 +375,6 @@ handle_gtid_pos_auto_create_request(THD *thd, void *hton)
it.
*/
mysql_mutex_lock(&LOCK_global_system_variables);
- engine= NULL;
for (auto_engines= opt_gtid_pos_auto_plugins;
auto_engines && *auto_engines;
++auto_engines)
@@ -419,6 +419,13 @@ handle_gtid_pos_auto_create_request(THD *thd, void *hton)
table_name.str= loc_table_name.c_ptr_safe();
table_name.length= loc_table_name.length();
+ thd= new THD(next_thread_id());
+ thd->thread_stack= (char*) &thd; /* Set approximate stack start */
+ thd->system_thread = SYSTEM_THREAD_SLAVE_BACKGROUND;
+ thd->store_globals();
+ thd->security_ctx->skip_grants();
+ thd->set_command(COM_DAEMON);
+ thd->variables.wsrep_on= 0;
err= gtid_pos_table_creation(thd, engine, &table_name);
if (err)
{
@@ -446,44 +453,23 @@ handle_gtid_pos_auto_create_request(THD *thd, void *hton)
mysql_mutex_unlock(&rpl_global_gtid_slave_state->LOCK_slave_state);
end:
+ delete thd;
if (engine)
plugin_unlock(NULL, engine);
}
-static bool slave_background_thread_running;
-static bool slave_background_thread_stop;
static bool slave_background_thread_gtid_loaded;
-static struct slave_background_kill_t {
- slave_background_kill_t *next;
- THD *to_kill;
-} *slave_background_kill_list;
-
-static struct slave_background_gtid_pos_create_t {
- slave_background_gtid_pos_create_t *next;
- void *hton;
-} *slave_background_gtid_pos_create_list;
-
-
-pthread_handler_t
-handle_slave_background(void *arg __attribute__((unused)))
+static void bg_rpl_load_gtid_slave_state(void *)
{
- THD *thd;
- PSI_stage_info old_stage;
- bool stop;
-
- my_thread_init();
- thd= new THD(next_thread_id());
+ THD *thd= new THD(next_thread_id());
thd->thread_stack= (char*) &thd; /* Set approximate stack start */
thd->system_thread = SYSTEM_THREAD_SLAVE_BACKGROUND;
- thread_safe_increment32(&service_thread_count);
thd->store_globals();
thd->security_ctx->skip_grants();
thd->set_command(COM_DAEMON);
-#ifdef WITH_WSREP
thd->variables.wsrep_on= 0;
-#endif
thd_proc_info(thd, "Loading slave GTID position from table");
if (rpl_load_gtid_slave_state(thd))
@@ -493,95 +479,32 @@ handle_slave_background(void *arg __attribute__((unused)))
thd->get_stmt_da()->sql_errno(),
thd->get_stmt_da()->message());
- mysql_mutex_lock(&LOCK_slave_background);
+ // hijacking global_rpl_thread_pool cond here - it's only once on startup
+ mysql_mutex_lock(&global_rpl_thread_pool.LOCK_rpl_thread_pool);
slave_background_thread_gtid_loaded= true;
- mysql_cond_broadcast(&COND_slave_background);
-
- THD_STAGE_INFO(thd, stage_slave_background_process_request);
- do
- {
- slave_background_kill_t *kill_list;
- slave_background_gtid_pos_create_t *create_list;
-
- thd->ENTER_COND(&COND_slave_background, &LOCK_slave_background,
- &stage_slave_background_wait_request,
- &old_stage);
- for (;;)
- {
- stop= abort_loop || thd->killed || slave_background_thread_stop;
- kill_list= slave_background_kill_list;
- create_list= slave_background_gtid_pos_create_list;
- if (stop || kill_list || create_list)
- break;
- mysql_cond_wait(&COND_slave_background, &LOCK_slave_background);
- }
-
- slave_background_kill_list= NULL;
- slave_background_gtid_pos_create_list= NULL;
- thd->EXIT_COND(&old_stage);
-
- while (kill_list)
- {
- slave_background_kill_t *p = kill_list;
- THD *to_kill= p->to_kill;
- kill_list= p->next;
-
- to_kill->awake(KILL_CONNECTION);
- mysql_mutex_lock(&to_kill->LOCK_wakeup_ready);
- to_kill->rgi_slave->killed_for_retry=
- rpl_group_info::RETRY_KILL_KILLED;
- mysql_cond_broadcast(&to_kill->COND_wakeup_ready);
- mysql_mutex_unlock(&to_kill->LOCK_wakeup_ready);
- my_free(p);
- }
-
- while (create_list)
- {
- slave_background_gtid_pos_create_t *next= create_list->next;
- void *hton= create_list->hton;
- handle_gtid_pos_auto_create_request(thd, hton);
- my_free(create_list);
- create_list= next;
- }
-
- mysql_mutex_lock(&LOCK_slave_background);
- } while (!stop);
-
- slave_background_thread_running= false;
- mysql_cond_broadcast(&COND_slave_background);
- mysql_mutex_unlock(&LOCK_slave_background);
-
+ mysql_cond_signal(&global_rpl_thread_pool.COND_rpl_thread_pool);
+ mysql_mutex_unlock(&global_rpl_thread_pool.LOCK_rpl_thread_pool);
delete thd;
- thread_safe_decrement32(&service_thread_count);
- signal_thd_deleted();
-
- my_thread_end();
- return 0;
}
+static void bg_slave_kill(void *victim)
+{
+ THD *to_kill= (THD *)victim;
+ to_kill->awake(KILL_CONNECTION);
+ mysql_mutex_lock(&to_kill->LOCK_wakeup_ready);
+ to_kill->rgi_slave->killed_for_retry= rpl_group_info::RETRY_KILL_KILLED;
+ mysql_cond_broadcast(&to_kill->COND_wakeup_ready);
+ mysql_mutex_unlock(&to_kill->LOCK_wakeup_ready);
+}
-
-void
-slave_background_kill_request(THD *to_kill)
+void slave_background_kill_request(THD *to_kill)
{
if (to_kill->rgi_slave->killed_for_retry)
return; // Already deadlock killed.
- slave_background_kill_t *p=
- (slave_background_kill_t *)my_malloc(sizeof(*p), MYF(MY_WME));
- if (p)
- {
- p->to_kill= to_kill;
- to_kill->rgi_slave->killed_for_retry=
- rpl_group_info::RETRY_KILL_PENDING;
- mysql_mutex_lock(&LOCK_slave_background);
- p->next= slave_background_kill_list;
- slave_background_kill_list= p;
- mysql_cond_signal(&COND_slave_background);
- mysql_mutex_unlock(&LOCK_slave_background);
- }
+ to_kill->rgi_slave->killed_for_retry= rpl_group_info::RETRY_KILL_PENDING;
+ mysql_manager_submit(bg_slave_kill, to_kill);
}
-
/*
This function must only be called from a slave SQL thread (or worker thread),
to ensure that the table_entry will not go away before we can lock the
@@ -591,80 +514,18 @@ void
slave_background_gtid_pos_create_request(
rpl_slave_state::gtid_pos_table *table_entry)
{
- slave_background_gtid_pos_create_t *p;
-
if (table_entry->state != rpl_slave_state::GTID_POS_AUTO_CREATE)
return;
- p= (slave_background_gtid_pos_create_t *)my_malloc(sizeof(*p), MYF(MY_WME));
- if (!p)
- return;
mysql_mutex_lock(&rpl_global_gtid_slave_state->LOCK_slave_state);
if (table_entry->state != rpl_slave_state::GTID_POS_AUTO_CREATE)
{
- my_free(p);
mysql_mutex_unlock(&rpl_global_gtid_slave_state->LOCK_slave_state);
return;
}
table_entry->state= rpl_slave_state::GTID_POS_CREATE_REQUESTED;
mysql_mutex_unlock(&rpl_global_gtid_slave_state->LOCK_slave_state);
- p->hton= table_entry->table_hton;
- mysql_mutex_lock(&LOCK_slave_background);
- p->next= slave_background_gtid_pos_create_list;
- slave_background_gtid_pos_create_list= p;
- mysql_cond_signal(&COND_slave_background);
- mysql_mutex_unlock(&LOCK_slave_background);
-}
-
-
-/*
- Start the slave background thread.
-
- This thread is currently used for two purposes:
-
- 1. To load the GTID state from mysql.gtid_slave_pos at server start; reading
- from table requires valid THD, which is otherwise not available during
- server init.
-
- 2. To kill worker thread transactions during parallel replication, when a
- storage engine attempts to take an errorneous conflicting lock that would
- cause a deadlock. Killing is done asynchroneously, as the kill may not
- be safe within the context of a callback from inside storage engine
- locking code.
-*/
-static int
-start_slave_background_thread()
-{
- pthread_t th;
-
- slave_background_thread_running= true;
- slave_background_thread_stop= false;
- slave_background_thread_gtid_loaded= false;
- if (mysql_thread_create(key_thread_slave_background,
- &th, &connection_attrib, handle_slave_background,
- NULL))
- {
- sql_print_error("Failed to create thread while initialising slave");
- return 1;
- }
- mysql_mutex_lock(&LOCK_slave_background);
- while (!slave_background_thread_gtid_loaded)
- mysql_cond_wait(&COND_slave_background, &LOCK_slave_background);
- mysql_mutex_unlock(&LOCK_slave_background);
-
- return 0;
-}
-
-
-static void
-stop_slave_background_thread()
-{
- mysql_mutex_lock(&LOCK_slave_background);
- slave_background_thread_stop= true;
- mysql_cond_broadcast(&COND_slave_background);
- while (slave_background_thread_running)
- mysql_cond_wait(&COND_slave_background, &LOCK_slave_background);
- mysql_mutex_unlock(&LOCK_slave_background);
+ mysql_manager_submit(bg_gtid_pos_auto_create, table_entry->table_hton);
}
@@ -679,12 +540,19 @@ int init_slave()
init_slave_psi_keys();
#endif
- if (start_slave_background_thread())
- return 1;
-
if (global_rpl_thread_pool.init(opt_slave_parallel_threads))
return 1;
+ slave_background_thread_gtid_loaded= false;
+ mysql_manager_submit(bg_rpl_load_gtid_slave_state, NULL);
+
+ // hijacking global_rpl_thread_pool cond here - it's only once on startup
+ mysql_mutex_lock(&global_rpl_thread_pool.LOCK_rpl_thread_pool);
+ while (!slave_background_thread_gtid_loaded)
+ mysql_cond_wait(&global_rpl_thread_pool.COND_rpl_thread_pool,
+ &global_rpl_thread_pool.LOCK_rpl_thread_pool);
+ mysql_mutex_unlock(&global_rpl_thread_pool.LOCK_rpl_thread_pool);
+
/*
This is called when mysqld starts. Before client connections are
accepted. However bootstrap may conflict with us if it does START SLAVE.
@@ -1393,7 +1261,6 @@ 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();
}
/*
@@ -1424,8 +1291,6 @@ void end_slave()
active_mi= 0;
mysql_mutex_unlock(&LOCK_active_mi);
- stop_slave_background_thread();
-
global_rpl_thread_pool.destroy();
free_all_rpl_filters();
DBUG_VOID_RETURN;
@@ -4681,10 +4546,7 @@ pthread_handler_t handle_slave_io(void *arg)
goto err;
}
-
-#ifdef WITH_WSREP
thd->variables.wsrep_on= 0;
-#endif
if (DBUG_EVALUATE_IF("failed_slave_start", 1, 0)
|| repl_semisync_slave.slave_start(mi))
{
@@ -5006,8 +4868,11 @@ log space");
err:
// print the current replication position
if (mi->using_gtid == Master_info::USE_GTID_NO)
+ {
sql_print_information("Slave I/O thread exiting, read up to log '%s', "
"position %llu", IO_RPL_LOG_NAME, mi->master_log_pos);
+ sql_print_information("master was %s:%d", mi->host, mi->port);
+ }
else
{
StringBuffer<100> tmp;
@@ -5016,6 +4881,7 @@ err:
"position %llu; GTID position %s",
IO_RPL_LOG_NAME, mi->master_log_pos,
tmp.c_ptr_safe());
+ sql_print_information("master was %s:%d", mi->host, mi->port);
}
repl_semisync_slave.slave_stop(mi);
thd->reset_query();
@@ -5614,6 +5480,7 @@ pthread_handler_t handle_slave_sql(void *arg)
sql_print_information("Slave SQL thread exiting, replication stopped in "
"log '%s' at position %llu%s", RPL_LOG_NAME,
rli->group_master_log_pos, tmp.c_ptr_safe());
+ sql_print_information("master was %s:%d", mi->host, mi->port);
}
err_before_start:
diff --git a/sql/spatial.cc b/sql/spatial.cc
index 2b36468e158..84a05532532 100644
--- a/sql/spatial.cc
+++ b/sql/spatial.cc
@@ -605,6 +605,7 @@ Geometry *Geometry::create_from_json(Geometry_buffer *buffer,
if (feature_type_found)
goto handle_geometry_key;
}
+ goto err_return;
}
else
{
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 205ab7f5974..1cc322092e2 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -2672,6 +2672,12 @@ end:
int acl_check_setrole(THD *thd, const char *rolename, ulonglong *access)
{
+ if (!initialized)
+ {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables");
+ return 1;
+ }
+
return check_user_can_set_role(thd, thd->security_ctx->priv_user,
thd->security_ctx->host, thd->security_ctx->ip, rolename, access);
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 174716c1c3e..224bded2026 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -448,6 +448,7 @@ void thd_set_ha_data(THD *thd, const struct handlerton *hton,
const void *ha_data)
{
plugin_ref *lock= &thd->ha_data[hton->slot].lock;
+ DBUG_ASSERT(thd == current_thd);
if (ha_data && !*lock)
*lock= ha_lock_engine(NULL, (handlerton*) hton);
else if (!ha_data && *lock)
@@ -455,7 +456,9 @@ void thd_set_ha_data(THD *thd, const struct handlerton *hton,
plugin_unlock(NULL, *lock);
*lock= NULL;
}
+ mysql_mutex_lock(&thd->LOCK_thd_data);
*thd_ha_data(thd, hton)= (void*) ha_data;
+ mysql_mutex_unlock(&thd->LOCK_thd_data);
}
@@ -1458,15 +1461,12 @@ void THD::reset_db(const LEX_CSTRING *new_db)
/* Do operations that may take a long time */
-void THD::cleanup(bool have_mutex)
+void THD::cleanup(void)
{
DBUG_ENTER("THD::cleanup");
DBUG_ASSERT(cleanup_done == 0);
- if (have_mutex)
- set_killed_no_mutex(KILL_CONNECTION,0,0);
- else
- set_killed(KILL_CONNECTION);
+ set_killed(KILL_CONNECTION);
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
if (transaction.xid_state.xa_state == XA_PREPARED)
{
@@ -1544,28 +1544,6 @@ void THD::cleanup(bool have_mutex)
void THD::free_connection()
{
DBUG_ASSERT(free_connection_done == 0);
- /* Check that we have already called thd->unlink() */
- DBUG_ASSERT(prev == 0 && next == 0);
-
- /*
- Other threads may have a lock on THD::LOCK_thd_data or
- THD::LOCK_thd_kill to ensure that this THD is not deleted
- while they access it. The following mutex_lock ensures
- that no one else is using this THD and it's now safe to
- continue.
-
- For example consider KILL-statement execution on
- sql_parse.cc kill_one_thread() that will use
- THD::LOCK_thd_data to protect victim thread during
- THD::awake().
- */
- mysql_mutex_lock(&LOCK_thd_data);
- mysql_mutex_lock(&LOCK_thd_kill);
-
-#ifdef WITH_WSREP
- delete wsrep_rgi;
- wsrep_rgi= 0;
-#endif /* WITH_WSREP */
my_free(const_cast<char*>(db.str));
db= null_clex_str;
#ifndef EMBEDDED_LIBRARY
@@ -1574,8 +1552,8 @@ void THD::free_connection()
net.vio= 0;
net_end(&net);
#endif
- if (!cleanup_done)
- cleanup(true); // We have locked THD::LOCK_thd_kill
+ if (!cleanup_done)
+ cleanup();
ha_close_connection(this);
plugin_thdvar_cleanup(this);
mysql_audit_free_thd(this);
@@ -1586,8 +1564,6 @@ void THD::free_connection()
#if defined(ENABLED_PROFILING)
profiling.restart(); // Reset profiling
#endif
- mysql_mutex_unlock(&LOCK_thd_kill);
- mysql_mutex_unlock(&LOCK_thd_data);
}
/*
@@ -1647,6 +1623,9 @@ THD::~THD()
mysql_mutex_lock(&LOCK_thd_kill);
mysql_mutex_unlock(&LOCK_thd_kill);
+#ifdef WITH_WSREP
+ delete wsrep_rgi;
+#endif
if (!free_connection_done)
free_connection();
@@ -5001,6 +4980,16 @@ thd_need_ordering_with(const MYSQL_THD thd, const MYSQL_THD other_thd)
DBUG_EXECUTE_IF("disable_thd_need_ordering_with", return 1;);
if (!thd || !other_thd)
return 1;
+#ifdef WITH_WSREP
+ /* wsrep applier, replayer and TOI processing threads are ordered
+ by replication provider, relaxed GAP locking protocol can be used
+ between high priority wsrep threads
+ */
+ if (WSREP_ON &&
+ wsrep_thd_is_BF(const_cast<THD *>(thd), false) &&
+ wsrep_thd_is_BF(const_cast<THD *>(other_thd), true))
+ return 0;
+#endif /* WITH_WSREP */
rgi= thd->rgi_slave;
other_rgi= other_thd->rgi_slave;
if (!rgi || !other_rgi)
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 140394fefc1..1fbd9c0206c 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -3291,7 +3291,7 @@ public:
void update_all_stats();
void update_stats(void);
void change_user(void);
- void cleanup(bool have_mutex=false);
+ void cleanup(void);
void cleanup_after_query();
void free_connection();
void reset_for_reuse();
@@ -6576,6 +6576,22 @@ class Sql_mode_save
sql_mode_t old_mode; // SQL mode saved at construction time.
};
+class Abort_on_warning_instant_set
+{
+ THD *m_thd;
+ bool m_save_abort_on_warning;
+public:
+ Abort_on_warning_instant_set(THD *thd, bool temporary_value)
+ :m_thd(thd), m_save_abort_on_warning(thd->abort_on_warning)
+ {
+ thd->abort_on_warning= temporary_value;
+ }
+ ~Abort_on_warning_instant_set()
+ {
+ m_thd->abort_on_warning= m_save_abort_on_warning;
+ }
+};
+
class Switch_to_definer_security_ctx
{
public:
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 59271694d8d..4d9ef98d22b 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -88,7 +88,6 @@ int get_or_create_user_conn(THD *thd, const char *user,
uc->host= uc->user + user_len + 1;
uc->len= (uint)temp_len;
uc->connections= uc->questions= uc->updates= uc->conn_per_hour= 0;
- uc->user_resources= *mqh;
uc->reset_utime= thd->thr_create_utime;
if (my_hash_insert(&hash_user_connections, (uchar*) uc))
{
@@ -98,6 +97,7 @@ int get_or_create_user_conn(THD *thd, const char *user,
goto end;
}
}
+ uc->user_resources= *mqh;
thd->user_connect=uc;
uc->connections++;
end:
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index b8f6610e066..9766a28757e 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -4864,6 +4864,9 @@ bool LEX::save_prep_leaf_tables()
bool st_select_lex::save_prep_leaf_tables(THD *thd)
{
+ if (prep_leaf_list_state == SAVED)
+ return FALSE;
+
List_iterator_fast<TABLE_LIST> li(leaf_tables);
TABLE_LIST *table;
diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc
index 2ad8d8a914a..b08e43e8af2 100644
--- a/sql/sql_manager.cc
+++ b/sql/sql_manager.cc
@@ -26,8 +26,8 @@
#include "sql_manager.h"
#include "sql_base.h" // flush_tables
-static bool volatile manager_thread_in_use;
-static bool abort_manager;
+static bool volatile manager_thread_in_use = 0;
+static bool abort_manager = false;
pthread_t manager_thread;
mysql_mutex_t LOCK_manager;
@@ -35,31 +35,31 @@ mysql_cond_t COND_manager;
struct handler_cb {
struct handler_cb *next;
- void (*action)(void);
+ void (*action)(void *);
+ void *data;
};
-static struct handler_cb * volatile cb_list;
+static struct handler_cb *cb_list; // protected by LOCK_manager
-bool mysql_manager_submit(void (*action)())
+bool mysql_manager_submit(void (*action)(void *), void *data)
{
bool result= FALSE;
DBUG_ASSERT(manager_thread_in_use);
- struct handler_cb * volatile *cb;
+ struct handler_cb **cb;
mysql_mutex_lock(&LOCK_manager);
cb= &cb_list;
- while (*cb && (*cb)->action != action)
+ while (*cb)
cb= &(*cb)->next;
+ *cb= (struct handler_cb *)my_malloc(sizeof(struct handler_cb), MYF(MY_WME));
if (!*cb)
+ result= TRUE;
+ else
{
- *cb= (struct handler_cb *)my_malloc(sizeof(struct handler_cb), MYF(MY_WME));
- if (!*cb)
- result= TRUE;
- else
- {
- (*cb)->next= NULL;
- (*cb)->action= action;
- }
+ (*cb)->next= NULL;
+ (*cb)->action= action;
+ (*cb)->data= data;
}
+ mysql_cond_signal(&COND_manager);
mysql_mutex_unlock(&LOCK_manager);
return result;
}
@@ -69,18 +69,14 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused)))
int error = 0;
struct timespec abstime;
bool reset_flush_time = TRUE;
- struct handler_cb *cb= NULL;
my_thread_init();
DBUG_ENTER("handle_manager");
pthread_detach_this_thread();
manager_thread = pthread_self();
- mysql_cond_init(key_COND_manager, &COND_manager,NULL);
- mysql_mutex_init(key_LOCK_manager, &LOCK_manager, NULL);
- manager_thread_in_use = 1;
- for (;;)
+ mysql_mutex_lock(&LOCK_manager);
+ while (!abort_manager)
{
- mysql_mutex_lock(&LOCK_manager);
/* XXX: This will need to be made more general to handle different
* polling needs. */
if (flush_time)
@@ -90,40 +86,37 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused)))
set_timespec(abstime, flush_time);
reset_flush_time = FALSE;
}
- while ((!error || error == EINTR) && !abort_manager)
+ while ((!error || error == EINTR) && !abort_manager && !cb_list)
error= mysql_cond_timedwait(&COND_manager, &LOCK_manager, &abstime);
+
+ if (error == ETIMEDOUT || error == ETIME)
+ {
+ tc_purge();
+ error = 0;
+ reset_flush_time = TRUE;
+ }
}
else
{
- while ((!error || error == EINTR) && !abort_manager)
+ while ((!error || error == EINTR) && !abort_manager && !cb_list)
error= mysql_cond_wait(&COND_manager, &LOCK_manager);
}
- if (cb == NULL)
- {
- cb= cb_list;
- cb_list= NULL;
- }
- mysql_mutex_unlock(&LOCK_manager);
- if (abort_manager)
- break;
-
- if (error == ETIMEDOUT || error == ETIME)
- {
- tc_purge();
- error = 0;
- reset_flush_time = TRUE;
- }
+ struct handler_cb *cb= cb_list;
+ cb_list= NULL;
+ mysql_mutex_unlock(&LOCK_manager);
while (cb)
{
struct handler_cb *next= cb->next;
- cb->action();
+ cb->action(cb->data);
my_free(cb);
cb= next;
}
+ mysql_mutex_lock(&LOCK_manager);
}
manager_thread_in_use = 0;
+ mysql_mutex_unlock(&LOCK_manager);
mysql_mutex_destroy(&LOCK_manager);
mysql_cond_destroy(&COND_manager);
DBUG_LEAVE; // Can't use DBUG_RETURN after my_thread_end
@@ -137,15 +130,15 @@ void start_handle_manager()
{
DBUG_ENTER("start_handle_manager");
abort_manager = false;
- if (flush_time && flush_time != ~(ulong) 0L)
{
pthread_t hThread;
- int error;
- if ((error= mysql_thread_create(key_thread_handle_manager,
- &hThread, &connection_attrib,
- handle_manager, 0)))
- sql_print_warning("Can't create handle_manager thread (errno= %d)",
- error);
+ int err;
+ manager_thread_in_use = 1;
+ mysql_cond_init(key_COND_manager, &COND_manager,NULL);
+ mysql_mutex_init(key_LOCK_manager, &LOCK_manager, NULL);
+ if ((err= mysql_thread_create(key_thread_handle_manager, &hThread,
+ &connection_attrib, handle_manager, 0)))
+ sql_print_warning("Can't create handle_manager thread (errno: %M)", err);
}
DBUG_VOID_RETURN;
}
@@ -155,10 +148,10 @@ void start_handle_manager()
void stop_handle_manager()
{
DBUG_ENTER("stop_handle_manager");
- abort_manager = true;
if (manager_thread_in_use)
{
mysql_mutex_lock(&LOCK_manager);
+ abort_manager = true;
DBUG_PRINT("quit", ("initiate shutdown of handle manager thread: %lu",
(ulong)manager_thread));
mysql_cond_signal(&COND_manager);
diff --git a/sql/sql_manager.h b/sql/sql_manager.h
index 9c6c84450ed..f97d4a2cfc5 100644
--- a/sql/sql_manager.h
+++ b/sql/sql_manager.h
@@ -18,6 +18,6 @@
void start_handle_manager();
void stop_handle_manager();
-bool mysql_manager_submit(void (*action)());
+bool mysql_manager_submit(void (*action)(void *), void *data);
#endif /* SQL_MANAGER_INCLUDED */
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index d24f7e4c7a7..66be72518ca 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2202,6 +2202,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break;
general_log_print(thd, command, NullS);
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]);
+ *current_global_status_var= global_status_var;
calc_sum_of_all_status(current_global_status_var);
if (!(uptime= (ulong) (thd->start_time - server_start_time)))
queries_per_second1000= 0;
diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h
index 352d1e22ac4..b266cdb8a9a 100644
--- a/sql/sql_plugin.h
+++ b/sql/sql_plugin.h
@@ -22,11 +22,12 @@
that is defined in plugin.h
*/
#define SHOW_always_last SHOW_KEY_CACHE_LONG, \
- SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, \
SHOW_HAVE, SHOW_MY_BOOL, SHOW_HA_ROWS, SHOW_SYS, \
- SHOW_LONG_NOFLUSH, SHOW_LONGLONG_STATUS, SHOW_UINT32_STATUS, \
- SHOW_LEX_STRING
-#include "mariadb.h"
+ SHOW_LONG_NOFLUSH, SHOW_LEX_STRING, \
+ /* SHOW_*_STATUS must be at the end, SHOW_LONG_STATUS being first */ \
+ SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, SHOW_LONGLONG_STATUS, \
+ SHOW_UINT32_STATUS
+#include <my_global.h>
#undef SHOW_always_last
#include "m_string.h" /* LEX_STRING */
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 4bc61fa5a25..3652a6ab086 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -121,6 +121,7 @@ When one supplies long data for a placeholder:
static const uint PARAMETER_FLAG_UNSIGNED= 128U << 8;
#endif
#include "lock.h" // MYSQL_OPEN_FORCE_SHARED_MDL
+#include "log_event.h" // class Log_event
#include "sql_handler.h"
#include "transaction.h" // trans_rollback_implicit
#include "wsrep_mysqld.h"
@@ -2470,6 +2471,16 @@ static bool check_prepared_statement(Prepared_statement *stmt)
DBUG_RETURN(FALSE);
}
break;
+ case SQLCOM_SHOW_BINLOG_EVENTS:
+ case SQLCOM_SHOW_RELAYLOG_EVENTS:
+ {
+ List<Item> field_list;
+ Log_event::init_show_field_list(thd, &field_list);
+
+ if ((res= send_stmt_metadata(thd, stmt, &field_list)) == 2)
+ DBUG_RETURN(FALSE);
+ }
+ break;
#endif /* EMBEDDED_LIBRARY */
case SQLCOM_SHOW_CREATE_PROC:
if ((res= mysql_test_show_create_routine(stmt, &sp_handler_procedure)) == 2)
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 4c3abc3c5a8..6a95a68864f 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -4585,5 +4585,22 @@ rpl_gtid_pos_update(THD *thd, char *str, size_t len)
return false;
}
+int compare_log_name(const char *log_1, const char *log_2) {
+ int res= 1;
+ const char *ext1_str= strrchr(log_1, '.');
+ const char *ext2_str= strrchr(log_2, '.');
+ char file_name_1[255], file_name_2[255];
+ strmake(file_name_1, log_1, (ext1_str - log_1));
+ strmake(file_name_2, log_2, (ext2_str - log_2));
+ char *endptr = NULL;
+ res= strcmp(file_name_1, file_name_2);
+ if (!res)
+ {
+ ulong ext1= strtoul(++ext1_str, &endptr, 10);
+ ulong ext2= strtoul(++ext2_str, &endptr, 10);
+ res= (ext1 > ext2 ? 1 : ((ext1 == ext2) ? 0 : -1));
+ }
+ return res;
+}
#endif /* HAVE_REPLICATION */
diff --git a/sql/sql_repl.h b/sql/sql_repl.h
index 8ddfa9239f6..9129aaeed5e 100644
--- a/sql/sql_repl.h
+++ b/sql/sql_repl.h
@@ -56,6 +56,7 @@ bool show_binlogs(THD* thd);
extern int init_master_info(Master_info* mi);
void kill_zombie_dump_threads(uint32 slave_server_id);
int check_binlog_magic(IO_CACHE* log, const char** errmsg);
+int compare_log_name(const char *log_1, const char *log_2);
struct LOAD_FILE_IO_CACHE : public IO_CACHE
{
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 2bb52788dcd..2e0a44e4b8a 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2244,8 +2244,13 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
/*
For string types dump collation name only if
collation is not primary for the given charset
+
+ For generated fields don't print the COLLATE clause if
+ the collation matches the expression's collation.
*/
- if (!(field->charset()->state & MY_CS_PRIMARY) && !field->vcol_info)
+ if (!(field->charset()->state & MY_CS_PRIMARY) &&
+ (!field->vcol_info ||
+ field->charset() != field->vcol_info->expr->collation.collation))
{
packet->append(STRING_WITH_LEN(" COLLATE "));
packet->append(field->charset()->name);
@@ -3794,6 +3799,16 @@ static bool show_status_array(THD *thd, const char *wild,
if (show_type == SHOW_SYS)
mysql_mutex_lock(&LOCK_global_system_variables);
+ else if (show_type >= SHOW_LONG_STATUS && scope == OPT_GLOBAL &&
+ !status_var->local_memory_used)
+ {
+ mysql_mutex_lock(&LOCK_status);
+ *status_var= global_status_var;
+ mysql_mutex_unlock(&LOCK_status);
+ calc_sum_of_all_status(status_var);
+ DBUG_ASSERT(status_var->local_memory_used);
+ }
+
pos= get_one_variable(thd, var, scope, show_type, status_var,
&charset, buff, &length);
@@ -3835,8 +3850,6 @@ uint calc_sum_of_all_status(STATUS_VAR *to)
I_List_iterator<THD> it(threads);
THD *tmp;
- /* Get global values as base */
- *to= global_status_var;
to->local_memory_used= 0;
/* Add to this status from existing threads */
@@ -5257,6 +5270,12 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
continue;
}
+ if (thd->killed == ABORT_QUERY)
+ {
+ error= 0;
+ goto err;
+ }
+
DEBUG_SYNC(thd, "before_open_in_get_all_tables");
if (fill_schema_table_by_open(thd, &tmp_mem_root, FALSE,
table, schema_table,
@@ -7919,13 +7938,7 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond)
if (partial_cond)
partial_cond->val_int();
- if (scope == OPT_GLOBAL)
- {
- /* We only hold LOCK_status for summary status vars */
- mysql_mutex_lock(&LOCK_status);
- calc_sum_of_all_status(&tmp);
- mysql_mutex_unlock(&LOCK_status);
- }
+ tmp.local_memory_used= 0; // meaning tmp was not populated yet
mysql_mutex_lock(&LOCK_show_status);
res= show_status_array(thd, wild,
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index 13532f5f171..dfce00f08a9 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -2108,6 +2108,10 @@ int alloc_statistics_for_table(THD* thd, TABLE *table)
ulonglong *idx_avg_frequency= (ulonglong*) alloc_root(&table->mem_root,
sizeof(ulonglong) * key_parts);
+ if (table->file->ha_rnd_init(TRUE))
+ DBUG_RETURN(1);
+ table->file->ha_rnd_end();
+
uint columns= 0;
for (field_ptr= table->field; *field_ptr; field_ptr++)
{
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 1237bba2286..54e382a6c24 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4045,8 +4045,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
{
/* not a critical problem */
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
- ER_TOO_LONG_KEY,
- ER_THD(thd, ER_TOO_LONG_KEY),
+ ER_TOO_LONG_KEY, ER_THD(thd, ER_TOO_LONG_KEY),
key_part_length);
/* Align key length to multibyte char boundary */
key_part_length-= key_part_length % sql_field->charset->mbmaxlen;
@@ -4092,7 +4091,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (key->type == Key::MULTIPLE)
{
/* not a critical problem */
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_TOO_LONG_KEY, ER_THD(thd, ER_TOO_LONG_KEY),
key_part_length);
/* Align key length to multibyte char boundary */
@@ -4329,7 +4328,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
ER_ILLEGAL_HA_CREATE_OPTION,
ER_THD(thd, ER_ILLEGAL_HA_CREATE_OPTION),
file->engine_name()->str,
- "TRANSACTIONAL=1");
+ create_info->transactional == HA_CHOICE_YES
+ ? "TRANSACTIONAL=1" : "TRANSACTIONAL=0");
if (parse_option_list(thd, file->partition_ht(), &create_info->option_struct,
&create_info->option_list,
@@ -5264,6 +5264,9 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
if (!opt_explicit_defaults_for_timestamp)
promote_first_timestamp_column(&alter_info->create_list);
+ /* We can abort create table for any table type */
+ thd->abort_on_warning= thd->is_strict_mode();
+
if (mysql_create_table_no_lock(thd, &create_table->db,
&create_table->table_name, create_info,
alter_info,
@@ -5301,6 +5304,8 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
}
err:
+ thd->abort_on_warning= 0;
+
/* In RBR or readonly server we don't need to log CREATE TEMPORARY TABLE */
if (!result && create_info->tmp_table() &&
(thd->is_current_stmt_binlog_format_row() || (opt_readonly && !thd->slave_thread)))
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index 0e73bfd7737..08552f1e919 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -565,6 +565,7 @@ void mysql_print_status()
STATUS_VAR tmp;
uint count;
+ tmp= global_status_var;
count= calc_sum_of_all_status(&tmp);
printf("\nStatus information:\n\n");
(void) my_getwd(current_dir, sizeof(current_dir),MYF(0));
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 3c40b003a3c..ff301267484 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1579,6 +1579,9 @@ bool Multiupdate_prelocking_strategy::handle_end(THD *thd)
if (select_lex->handle_derived(thd->lex, DT_MERGE))
DBUG_RETURN(1);
+ if (thd->lex->save_prep_leaf_tables())
+ DBUG_RETURN(1);
+
List<Item> *fields= &lex->select_lex.item_list;
if (setup_fields_with_no_wrap(thd, Ref_ptr_array(),
*fields, MARK_COLUMNS_WRITE, 0, 0))
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index cf2cab5bc15..88f12e97bfa 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -894,7 +894,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
/*
We should not introduce any further shift/reduce conflicts.
*/
-%expect 60
+%expect 81
/*
Comments for TOKENS.
@@ -1860,7 +1860,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <type_handler> int_type real_type
-%type <Lex_field_type> type_with_opt_collate field_type
+%type <Lex_field_type> field_type field_type_all
qualified_field_type
field_type_numeric
field_type_string
@@ -3390,7 +3390,7 @@ sp_param_name:
;
sp_param_name_and_type:
- sp_param_name type_with_opt_collate
+ sp_param_name field_type
{
if (unlikely(Lex->sp_param_fill_definition($$= $1)))
MYSQL_YYABORT;
@@ -3536,7 +3536,7 @@ row_field_name:
;
row_field_definition:
- row_field_name type_with_opt_collate
+ row_field_name field_type
;
row_field_definition_list:
@@ -3570,7 +3570,7 @@ sp_decl_idents_init_vars:
sp_decl_variable_list:
sp_decl_idents_init_vars
- type_with_opt_collate
+ field_type
sp_opt_default
{
if (unlikely(Lex->sp_variable_declarations_finalize(thd, $1,
@@ -6922,19 +6922,26 @@ column_default_expr:
}
;
+field_type: field_type_all
+ {
+ Lex->map_data_type(Lex_ident_sys(), &($$= $1));
+ Lex->last_field->set_attributes($$, Lex->charset);
+ }
+ ;
+
qualified_field_type:
- field_type
+ field_type_all
{
Lex->map_data_type(Lex_ident_sys(), &($$= $1));
}
- | sp_decl_ident '.' field_type
+ | sp_decl_ident '.' field_type_all
{
if (Lex->map_data_type($1, &($$= $3)))
MYSQL_YYABORT;
}
;
-field_type:
+field_type_all:
field_type_numeric
| field_type_temporal
| field_type_string
@@ -7397,20 +7404,6 @@ with_or_without_system:
;
-type_with_opt_collate:
- field_type opt_collate
- {
- Lex->map_data_type(Lex_ident_sys(), &($$= $1));
-
- if ($2)
- {
- if (unlikely(!(Lex->charset= merge_charset_and_collation(Lex->charset, $2))))
- MYSQL_YYABORT;
- }
- Lex->last_field->set_attributes($$, Lex->charset);
- }
- ;
-
charset:
CHAR_SYM SET {}
| CHARSET {}
@@ -7484,6 +7477,12 @@ charset_or_alias:
}
;
+collate: COLLATE_SYM collation_name_or_default
+ {
+ Lex->charset= $2;
+ }
+ ;
+
opt_binary:
/* empty */ { bincmp_collation(NULL, false); }
| binary {}
@@ -7494,6 +7493,13 @@ binary:
| charset_or_alias opt_bin_mod { bincmp_collation($1, $2); }
| BINARY { bincmp_collation(NULL, true); }
| BINARY charset_or_alias { bincmp_collation($2, true); }
+ | charset_or_alias collate
+ {
+ if (!my_charset_same(Lex->charset, $1))
+ my_yyabort_error((ER_COLLATION_CHARSET_MISMATCH, MYF(0),
+ Lex->charset->name, $1->csname));
+ }
+ | collate { }
;
opt_bin_mod:
@@ -14763,7 +14769,7 @@ kill:
lex->sql_command= SQLCOM_KILL;
lex->kill_type= KILL_TYPE_ID;
}
- kill_type kill_option kill_expr
+ kill_type kill_option
{
Lex->kill_signal= (killed_state) ($3 | $4);
}
@@ -14776,16 +14782,21 @@ kill_type:
;
kill_option:
- /* empty */ { $$= (int) KILL_CONNECTION; }
- | CONNECTION_SYM { $$= (int) KILL_CONNECTION; }
- | QUERY_SYM { $$= (int) KILL_QUERY; }
- | QUERY_SYM ID_SYM
+ opt_connection kill_expr { $$= (int) KILL_CONNECTION; }
+ | QUERY_SYM kill_expr { $$= (int) KILL_QUERY; }
+ | QUERY_SYM ID_SYM expr
{
$$= (int) KILL_QUERY;
Lex->kill_type= KILL_TYPE_QUERY;
+ Lex->value_list.push_front($3, thd->mem_root);
}
;
+opt_connection:
+ /* empty */ { }
+ | CONNECTION_SYM { }
+ ;
+
kill_expr:
expr
{
@@ -14798,7 +14809,6 @@ kill_expr:
}
;
-
shutdown:
SHUTDOWN { Lex->sql_command= SQLCOM_SHUTDOWN; }
;
@@ -17969,7 +17979,7 @@ sf_return_type:
&empty_clex_str,
thd->variables.collation_database);
}
- type_with_opt_collate
+ field_type
{
if (unlikely(Lex->sphead->fill_field_definition(thd,
Lex->last_field)))
diff --git a/sql/unireg.cc b/sql/unireg.cc
index b31e3542463..86a58db2f9d 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -1032,6 +1032,8 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options,
TABLE table;
TABLE_SHARE share;
Create_field *field;
+ Check_level_instant_set old_count_cuted_fields(thd, CHECK_FIELD_WARN);
+ Abort_on_warning_instant_set old_abort_on_warning(thd, 0);
DBUG_ENTER("make_empty_rec");
/* We need a table to generate columns for default values */
@@ -1050,7 +1052,6 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options,
null_pos= buff;
List_iterator<Create_field> it(create_fields);
- Check_level_instant_set check_level_save(thd, CHECK_FIELD_WARN);
while ((field=it++))
{
/* regfield don't have to be deleted as it's allocated on THD::mem_root */
diff --git a/sql/upgrade_conf_file.cc b/sql/upgrade_conf_file.cc
index 4e167f0263f..b40cce0bbd7 100644
--- a/sql/upgrade_conf_file.cc
+++ b/sql/upgrade_conf_file.cc
@@ -75,6 +75,7 @@ static const char *removed_variables[] =
"innodb_ibuf_accel_rate",
"innodb_ibuf_active_contract",
"innodb_ibuf_max_size",
+"innodb_idle_flush_pct",
"innodb_import_table_from_xtrabackup",
"innodb_instrument_semaphores",
"innodb_kill_idle_transaction",
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index 3aac0556a2c..2d7d6748c2e 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -143,6 +143,12 @@ static bool sst_auth_real_set (const char* value)
if (wsrep_sst_auth) { my_free((void*) wsrep_sst_auth); }
wsrep_sst_auth= my_strdup(WSREP_SST_AUTH_MASK, MYF(0));
}
+ else
+ {
+ if (wsrep_sst_auth) { my_free((void*) wsrep_sst_auth); }
+ wsrep_sst_auth= NULL;
+ }
+
return 0;
}
return 1;
diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc
index c06c195e69f..640401cb1bf 100644
--- a/sql/wsrep_thd.cc
+++ b/sql/wsrep_thd.cc
@@ -22,6 +22,7 @@
//#include "global_threads.h" // LOCK_thread_count, etc.
#include "sql_base.h" // close_thread_tables()
#include "mysqld.h" // start_wsrep_THD();
+#include "debug_sync.h"
#include "slave.h" // opt_log_slave_updates
#include "rpl_filter.h"
@@ -372,6 +373,19 @@ void wsrep_replay_transaction(THD *thd)
thd->variables.option_bits|= OPTION_BEGIN;
thd->server_status|= SERVER_STATUS_IN_TRANS;
+ /* Allow tests to block the replayer thread using the DBUG facilities */
+#ifdef ENABLED_DEBUG_SYNC
+ DBUG_EXECUTE_IF("sync.wsrep_replay_cb",
+ {
+ const char act[]=
+ "now "
+ "SIGNAL sync.wsrep_replay_cb_reached "
+ "WAIT_FOR signal.wsrep_replay_cb";
+ DBUG_ASSERT(!debug_sync_set_action(thd,
+ STRING_WITH_LEN(act)));
+ };);
+#endif /* ENABLED_DEBUG_SYNC */
+
int rcode = wsrep->replay_trx(wsrep,
&thd->wsrep_ws_handle,
(void *)thd);