summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2018-05-07 13:49:14 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2018-05-07 13:49:14 +0300
commit648cf7176cc95f697abd8b94e860c74768680298 (patch)
tree8f3d19e0f1bd607cb515111f106715f9a4e6fcec /sql
parent7b115181987fb88b97ef6d3d88bb16bdbc281e40 (diff)
parent1ecd68d867ced1d00ebffdcedbf6bc97493f5067 (diff)
downloadmariadb-git-648cf7176cc95f697abd8b94e860c74768680298.tar.gz
Merge remote-tracking branch 'origin/5.5-galera' into 10.0-galera
Diffstat (limited to 'sql')
-rw-r--r--sql/event_data_objects.cc21
-rw-r--r--sql/event_db_repository.cc5
-rw-r--r--sql/events.cc15
-rw-r--r--sql/handler.cc6
-rw-r--r--sql/item_cmpfunc.h5
-rw-r--r--sql/item_func.h4
-rw-r--r--sql/item_strfunc.h2
-rw-r--r--sql/item_subselect.cc2
-rw-r--r--sql/log.cc8
-rw-r--r--sql/log_event.cc69
-rw-r--r--sql/log_event_old.cc3
-rw-r--r--sql/mysqld.cc5
-rw-r--r--sql/mysqld.h3
-rw-r--r--sql/opt_subselect.cc9
-rw-r--r--sql/slave.cc2
-rw-r--r--sql/sp.cc6
-rw-r--r--sql/sql_acl.cc3
-rw-r--r--sql/sql_admin.cc2
-rw-r--r--sql/sql_base.h2
-rw-r--r--sql/sql_cache.cc1
-rw-r--r--sql/sql_class.cc7
-rw-r--r--sql/sql_class.h1
-rw-r--r--sql/sql_insert.cc29
-rw-r--r--sql/sql_parse.cc14
-rw-r--r--sql/sql_partition.cc2
-rw-r--r--sql/sql_plugin.cc33
-rw-r--r--sql/sql_prepare.cc6
-rw-r--r--sql/sql_priv.h4
-rw-r--r--sql/sql_table.cc2
-rw-r--r--sql/sql_trigger.cc6
-rw-r--r--sql/sql_truncate.cc2
-rw-r--r--sql/sql_update.cc2
-rw-r--r--sql/sql_view.cc5
-rw-r--r--sql/sql_yacc.yy5
-rw-r--r--sql/sys_vars.cc6
-rw-r--r--sql/table.cc16
-rw-r--r--sql/table.h8
-rw-r--r--sql/wsrep_hton.cc38
-rw-r--r--sql/wsrep_mysqld.cc65
-rw-r--r--sql/wsrep_mysqld.h13
-rw-r--r--sql/wsrep_priv.h2
-rw-r--r--sql/wsrep_sst.cc1
-rw-r--r--sql/wsrep_thd.cc2
-rw-r--r--sql/wsrep_utils.cc1
44 files changed, 327 insertions, 116 deletions
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index e7bdc42b2e6..aa85b570a84 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -1473,23 +1473,22 @@ end:
thd->tx_read_only= false;
#ifdef WITH_WSREP
- if (WSREP(thd)) {
- // sql_print_information("sizeof(LEX) = %d", sizeof(struct LEX));
- // sizeof(LEX) = 4512, so it's relatively safe to allocate it on stack.
- LEX lex;
- LEX* saved = thd->lex;
- lex.sql_command = SQLCOM_DROP_EVENT;
- thd->lex = &lex;
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
- thd->lex = saved;
+ const bool sql_command_set= WSREP(thd);
+ const enum_sql_command sql_command_save= thd->lex->sql_command;
+
+ if (sql_command_set) {
+ thd->lex->sql_command = SQLCOM_DROP_EVENT;
}
#endif
ret= Events::drop_event(thd, dbname, name, FALSE);
#ifdef WITH_WSREP
- WSREP_TO_ISOLATION_END;
- error:
+ if (sql_command_set)
+ {
+ WSREP_TO_ISOLATION_END;
+ thd->lex->sql_command = sql_command_save;
+ }
#endif
thd->tx_read_only= save_tx_read_only;
thd->security_ctx->master_access= saved_master_access;
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index 66606b18c49..22e001a7b91 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2006, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2006, 2017, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2018, MariaDB
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
@@ -177,6 +178,8 @@ protected:
error_log_print(ERROR_LEVEL, fmt, args);
va_end(args);
}
+public:
+ Event_db_intact() { has_keys= TRUE; }
};
/** In case of an error, a message is printed to the error log. */
diff --git a/sql/events.cc b/sql/events.cc
index dd4e4887d50..661d9e19001 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -331,6 +331,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
if (check_access(thd, EVENT_ACL, parse_data->dbname.str, NULL, NULL, 0, 0))
DBUG_RETURN(TRUE);
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
if (check_db_dir_existence(parse_data->dbname.str))
{
@@ -409,6 +410,10 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
thd->restore_stmt_binlog_format(save_binlog_format);
DBUG_RETURN(ret);
+#ifdef WITH_WSREP
+ error:
+ DBUG_RETURN(TRUE);
+#endif /* WITH_WSREP */
}
@@ -449,6 +454,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data,
if (check_access(thd, EVENT_ACL, parse_data->dbname.str, NULL, NULL, 0, 0))
DBUG_RETURN(TRUE);
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
if (new_dbname) /* It's a rename */
{
@@ -520,6 +526,10 @@ Events::update_event(THD *thd, Event_parse_data *parse_data,
thd->restore_stmt_binlog_format(save_binlog_format);
DBUG_RETURN(ret);
+#ifdef WITH_WSREP
+ error:
+ DBUG_RETURN(TRUE);
+#endif /* WITH_WSREP */
}
@@ -559,6 +569,7 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists)
if (check_access(thd, EVENT_ACL, dbname.str, NULL, NULL, 0, 0))
DBUG_RETURN(TRUE);
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
/*
Turn off row binlogging of this statement and use statement-based so
@@ -581,6 +592,10 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists)
thd->restore_stmt_binlog_format(save_binlog_format);
DBUG_RETURN(ret);
+#ifdef WITH_WSREP
+ error:
+ DBUG_RETURN(TRUE);
+#endif /* WITH_WSREP */
}
diff --git a/sql/handler.cc b/sql/handler.cc
index 657cb01cbc8..fc8bb53f35d 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -4463,6 +4463,7 @@ handler::ha_create_partitioning_metadata(const char *name, const char *old_name,
*/
DBUG_ASSERT(m_lock_type == F_UNLCK ||
(!old_name && strcmp(name, table_share->path.str)));
+
mark_trx_read_write();
return create_partitioning_metadata(name, old_name, action_flag);
@@ -6364,6 +6365,11 @@ void ha_wsrep_fake_trx_id(THD *thd)
DBUG_VOID_RETURN;
}
+ if (thd->wsrep_ws_handle.trx_id != WSREP_UNDEFINED_TRX_ID)
+ {
+ WSREP_DEBUG("fake trx id skipped: %lu", thd->wsrep_ws_handle.trx_id);
+ DBUG_VOID_RETURN;
+ }
handlerton *hton= installed_htons[DB_TYPE_INNODB];
if (hton && hton->wsrep_fake_trx_id)
{
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 6d81c7acc40..6cd7e0e3e78 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -260,6 +260,7 @@ public:
bool is_null();
longlong val_int();
void cleanup();
+ enum Functype functype() const { return IN_OPTIMIZER_FUNC; }
const char *func_name() const { return "<in_optimizer>"; }
Item_cache **get_cache() { return &cache; }
void keep_top_level_cache();
@@ -277,6 +278,10 @@ public:
void reset_cache() { cache= NULL; }
virtual void print(String *str, enum_query_type query_type);
void restore_first_argument();
+ Item* get_wrapped_in_subselect_item()
+ {
+ return args[1];
+ }
};
class Comp_creator
diff --git a/sql/item_func.h b/sql/item_func.h
index 7dea193c99b..b0ba87b4bd0 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -73,7 +73,7 @@ public:
NOW_FUNC, TRIG_COND_FUNC,
SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC,
- NEG_FUNC, GSYSVAR_FUNC, DYNCOL_FUNC };
+ NEG_FUNC, GSYSVAR_FUNC, IN_OPTIMIZER_FUNC, DYNCOL_FUNC };
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
OPTIMIZE_EQUAL };
enum Type type() const { return FUNC_ITEM; }
@@ -2201,6 +2201,8 @@ public:
Item_func_uuid_short() :Item_int_func() {}
const char *func_name() const { return "uuid_short"; }
longlong val_int();
+ bool const_item() const { return false; }
+ table_map used_tables() const { return RAND_TABLE_BIT; }
void fix_length_and_dec()
{ max_length= 21; unsigned_flag=1; }
bool check_vcol_func_processor(uchar *int_arg)
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index aa3486d4e73..c851728c9fa 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -1134,6 +1134,8 @@ public:
DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
fix_char_length(MY_UUID_STRING_LENGTH);
}
+ bool const_item() const { return false; }
+ table_map used_tables() const { return RAND_TABLE_BIT; }
const char *func_name() const{ return "uuid"; }
String *val_str(String *);
bool check_vcol_func_processor(uchar *int_arg)
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 8e8748be87a..f56b5f6e707 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1763,7 +1763,7 @@ Item_in_subselect::single_value_transformer(JOIN *join)
Item* join_having= join->having ? join->having : join->tmp_having;
if (!(join_having || select_lex->with_sum_func ||
select_lex->group_list.elements) &&
- select_lex->table_list.elements == 0 &&
+ select_lex->table_list.elements == 0 && !join->conds &&
!select_lex->master_unit()->is_union())
{
Item *where_item= (Item*) select_lex->item_list.head();
diff --git a/sql/log.cc b/sql/log.cc
index b63d72f0d4a..0098dd2ba3d 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -2631,7 +2631,7 @@ bool MYSQL_LOG::open(
File file= -1;
my_off_t seek_offset;
bool is_fifo = false;
- int open_flags= O_CREAT | O_BINARY;
+ int open_flags= O_CREAT | O_BINARY | O_CLOEXEC;
DBUG_ENTER("MYSQL_LOG::open");
DBUG_PRINT("enter", ("log_type: %d", (int) log_type_arg));
@@ -3316,7 +3316,7 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
".index", opt);
if ((index_file_nr= mysql_file_open(m_key_file_log_index,
index_file_name,
- O_RDWR | O_CREAT | O_BINARY,
+ O_RDWR | O_CREAT | O_BINARY | O_CLOEXEC,
MYF(MY_WME))) < 0 ||
mysql_file_sync(index_file_nr, MYF(MY_WME)) ||
init_io_cache(&index_file, index_file_nr,
@@ -8591,14 +8591,14 @@ int TC_LOG_MMAP::open(const char *opt_name)
tc_log_page_size= my_getpagesize();
fn_format(logname,opt_name,mysql_data_home,"",MY_UNPACK_FILENAME);
- if ((fd= mysql_file_open(key_file_tclog, logname, O_RDWR, MYF(0))) < 0)
+ if ((fd= mysql_file_open(key_file_tclog, logname, O_RDWR | O_CLOEXEC, MYF(0))) < 0)
{
if (my_errno != ENOENT)
goto err;
if (using_heuristic_recover())
return 1;
if ((fd= mysql_file_create(key_file_tclog, logname, CREATE_MODE,
- O_RDWR, MYF(MY_WME))) < 0)
+ O_RDWR | O_CLOEXEC, MYF(MY_WME))) < 0)
goto err;
inited=1;
file_length= opt_tc_log_size;
diff --git a/sql/log_event.cc b/sql/log_event.cc
index c57331df807..e799f37ddae 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1,6 +1,6 @@
/*
- Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2009, 2016, MariaDB
+ Copyright (c) 2000, 2018, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2018, MariaDB
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
@@ -3674,6 +3674,25 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
db= (char *)start;
query= (char *)(start + db_len + 1);
q_len= data_len - db_len -1;
+
+ if (data_len && (data_len < db_len ||
+ data_len < q_len ||
+ data_len != (db_len + q_len + 1)))
+ {
+ q_len= 0;
+ query= NULL;
+ DBUG_VOID_RETURN;
+ }
+
+ unsigned int max_length;
+ max_length= (event_len - ((const char*)(end + db_len + 1) -
+ (buf - common_header_len)));
+ if (q_len != max_length)
+ {
+ q_len= 0;
+ query= NULL;
+ DBUG_VOID_RETURN;
+ }
/**
Append the db length at the end of the buffer. This will be used by
Query_cache::send_result_to_client() in case the query cache is On.
@@ -4144,6 +4163,20 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
you.
*/
thd->catalog= catalog_len ? (char *) catalog : (char *)"";
+
+ int len_error;
+ size_t valid_len= system_charset_info->cset->well_formed_len(system_charset_info,
+ db, db + db_len, db_len, &len_error);
+
+ if (valid_len != db_len)
+ {
+ rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
+ ER_THD(thd, ER_SLAVE_FATAL_ERROR),
+ "Invalid database name in Query event.");
+ thd->is_slave_error= true;
+ goto end;
+ }
+
new_db.length= db_len;
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
thd->set_db(new_db.str, new_db.length); /* allocates a copy of 'db' */
@@ -4314,7 +4347,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
}
else
thd->variables.collation_database= thd->db_charset;
-
+
/*
Record any GTID in the same transaction, so slave state is
transactionally consistent.
@@ -4860,7 +4893,13 @@ int Start_log_event_v3::do_apply_event(rpl_group_info *rgi)
*/
break;
default:
- /* this case is impossible */
+ /*
+ This case is not expected. It can be either an event corruption or an
+ unsupported binary log version.
+ */
+ rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
+ ER_THD(thd, ER_SLAVE_FATAL_ERROR),
+ "Binlog version not supported");
DBUG_RETURN(1);
}
DBUG_RETURN(error);
@@ -5698,6 +5737,9 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
fields = (char*)field_lens + num_fields;
table_name = fields + field_block_len;
+ if (strlen(table_name) > NAME_LEN)
+ goto err;
+
db = table_name + table_name_len + 1;
DBUG_EXECUTE_IF ("simulate_invalid_address",
db_len = data_len;);
@@ -7647,6 +7689,13 @@ User_var_log_event(const char* buf, uint event_len,
buf+= description_event->common_header_len +
description_event->post_header_len[USER_VAR_EVENT-1];
name_len= uint4korr(buf);
+ /* Avoid reading out of buffer */
+ if ((buf - buf_start) + UV_NAME_LEN_SIZE + name_len > event_len)
+ {
+ error= true;
+ goto err;
+ }
+
name= (char *) buf + UV_NAME_LEN_SIZE;
/*
@@ -7704,6 +7753,11 @@ User_var_log_event(const char* buf, uint event_len,
we keep the flags set to UNDEF_F.
*/
uint bytes_read= ((val + val_len) - buf_start);
+ if (bytes_read > event_len)
+ {
+ error= true;
+ goto err;
+ }
if ((data_written - bytes_read) > 0)
{
flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
@@ -9513,7 +9567,12 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
- size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf);
+ size_t const read_size= ptr_rows_data - (const unsigned char *) buf;
+ if (read_size > event_len)
+ {
+ DBUG_VOID_RETURN;
+ }
+ size_t const data_size= event_len - read_size;
DBUG_PRINT("info",("m_table_id: %lu m_flags: %d m_width: %lu data_size: %lu",
m_table_id, m_flags, m_width, (ulong) data_size));
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index 73869e82f72..34c586510a3 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2007, 2016, Oracle and/or its affiliates.
+/* Copyright (c) 2007, 2018, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2018, MariaDB
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
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 8575709203c..f558b78104f 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2008, 2016, MariaDB
+ Copyright (c) 2008, 2018, MariaDB
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
@@ -1051,7 +1051,7 @@ PSI_cond_key key_BINLOG_COND_xid_list, key_BINLOG_update_cond,
key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache,
key_BINLOG_COND_queue_busy;
#ifdef WITH_WSREP
-PSI_cond_key key_COND_wsrep_rollback,
+PSI_cond_key key_COND_wsrep_rollback, key_COND_wsrep_thd,
key_COND_wsrep_replaying, key_COND_wsrep_ready, key_COND_wsrep_sst,
key_COND_wsrep_sst_init, key_COND_wsrep_sst_thread;
#endif /* WITH_WSREP */
@@ -1110,6 +1110,7 @@ static PSI_cond_info all_server_conds[]=
{ &key_COND_wsrep_sst_init, "COND_wsrep_sst_init", PSI_FLAG_GLOBAL},
{ &key_COND_wsrep_sst_thread, "wsrep_sst_thread", 0},
{ &key_COND_wsrep_rollback, "COND_wsrep_rollback", PSI_FLAG_GLOBAL},
+ { &key_COND_wsrep_thd, "THD::COND_wsrep_thd", 0},
{ &key_COND_wsrep_replaying, "COND_wsrep_replaying", PSI_FLAG_GLOBAL},
#endif
{ &key_COND_flush_thread_cache, "COND_flush_thread_cache", PSI_FLAG_GLOBAL},
diff --git a/sql/mysqld.h b/sql/mysqld.h
index 4af04a3df75..3bb9f35077e 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -250,7 +250,8 @@ extern PSI_mutex_key key_PAGE_lock, key_LOCK_sync, key_LOCK_active,
#ifdef WITH_WSREP
extern PSI_mutex_key key_LOCK_wsrep_thd;
-#endif /* WITH_WSREP */
+extern PSI_cond_key key_COND_wsrep_thd;
+#endif /* HAVE_WSREP */
#ifdef HAVE_OPENSSL
extern PSI_mutex_key key_LOCK_des_key_file;
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 67205a52cac..a9e21e67f13 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -873,8 +873,10 @@ bool subquery_types_allow_materialization(Item_in_subselect *in_subs)
Make sure that create_tmp_table will not fail due to too long keys.
See MDEV-7122. This check is performed inside create_tmp_table also and
we must do it so that we know the table has keys created.
+ Make sure that the length of the key for the temp_table is atleast
+ greater than 0.
*/
- if (total_key_length > tmp_table_max_key_length() ||
+ if (!total_key_length || total_key_length > tmp_table_max_key_length() ||
elements > tmp_table_max_key_parts())
DBUG_RETURN(FALSE);
@@ -1004,6 +1006,10 @@ bool check_for_outer_joins(List<TABLE_LIST> *join_list)
void find_and_block_conversion_to_sj(Item *to_find,
List_iterator_fast<Item_in_subselect> &li)
{
+ if (to_find->type() == Item::FUNC_ITEM &&
+ ((Item_func*)to_find)->functype() == Item_func::IN_OPTIMIZER_FUNC)
+ to_find= ((Item_in_optimizer*)to_find)->get_wrapped_in_subselect_item();
+
if (to_find->type() != Item::SUBSELECT_ITEM ||
((Item_subselect *) to_find)->substype() != Item_subselect::IN_SUBS)
return;
@@ -5954,5 +5960,6 @@ bool JOIN::choose_tableless_subquery_plan()
tmp_having= having;
}
}
+ exec_const_cond= conds;
return FALSE;
}
diff --git a/sql/slave.cc b/sql/slave.cc
index a633722db16..3dee39ad65f 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -4950,7 +4950,7 @@ err_during_init:
*/
if (wsrep_node_dropped && wsrep_restart_slave)
{
- if (wsrep_ready)
+ if (wsrep_ready_get())
{
WSREP_INFO("Slave error due to node temporarily non-primary"
"SQL slave will continue");
diff --git a/sql/sp.cc b/sql/sp.cc
index 78de0209e6f..ccdc53429bf 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -1,6 +1,6 @@
/*
- Copyright (c) 2002, 2016, Oracle and/or its affiliates.
- Copyright (c) 2009, 2017, MariaDB
+ Copyright (c) 2002, 2018, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2018, MariaDB
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
@@ -356,7 +356,7 @@ private:
bool m_print_once;
public:
- Proc_table_intact() : m_print_once(TRUE) {}
+ Proc_table_intact() : m_print_once(TRUE) { has_keys= TRUE; }
protected:
void report_error(uint code, const char *fmt, ...);
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index f08bd8a564d..ce3198e2bc5 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2009, 2016, MariaDB
+ Copyright (c) 2009, 2018, MariaDB
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
@@ -11212,6 +11212,7 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio,
const char *client_auth_plugin=
((st_mysql_auth *) (plugin_decl(mpvio->plugin)->info))->client_auth_plugin;
+ DBUG_EXECUTE_IF("auth_disconnect", { vio_close(net->vio); DBUG_RETURN(1); });
DBUG_ASSERT(client_auth_plugin);
/*
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index c5e11b7f4c1..a35e28ee421 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates.
- Copyright (c) 2011, 2016, MariaDB
+ Copyright (c) 2011, 2018, MariaDB
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
diff --git a/sql/sql_base.h b/sql/sql_base.h
index 711e7162550..04f132ac936 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -1,4 +1,6 @@
/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2011, 2018, MariaDB
+
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
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index e0818da325a..2c9eadf48c8 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -2559,6 +2559,7 @@ void Query_cache::init()
*/
if (global_system_variables.query_cache_type == 0)
{
+ m_cache_status= DISABLE_REQUEST;
free_cache();
m_cache_status= DISABLED;
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 2502962cef0..b3d964d4006 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1199,6 +1199,7 @@ THD::THD()
#ifdef WITH_WSREP
mysql_mutex_init(key_LOCK_wsrep_thd, &LOCK_wsrep_thd, MY_MUTEX_INIT_FAST);
+ mysql_cond_init(key_COND_wsrep_thd, &COND_wsrep_thd, NULL);
wsrep_ws_handle.trx_id = WSREP_UNDEFINED_TRX_ID;
wsrep_ws_handle.opaque = NULL;
wsrep_retry_counter = 0;
@@ -2730,15 +2731,19 @@ void THD::check_and_register_item_tree_change(Item **place, Item **new_value,
void THD::rollback_item_tree_changes()
{
+ DBUG_ENTER("THD::rollback_item_tree_changes");
I_List_iterator<Item_change_record> it(change_list);
Item_change_record *change;
while ((change= it++))
{
+ DBUG_PRINT("info", ("Rollback: %p (%p) <- %p",
+ *change->place, change->place, change->old_value));
*change->place= change->old_value;
}
/* We can forget about changes memory: it's allocated in runtime memroot */
change_list.empty();
+ DBUG_VOID_RETURN;
}
@@ -4785,7 +4790,7 @@ extern "C" int thd_binlog_format(const MYSQL_THD thd)
if (mysql_bin_log.is_open() && (thd->variables.option_bits & OPTION_BIN_LOG))
return (int) thd->variables.binlog_format;
else
- return BINLOG_FORMAT_UNSPEC;
+ return BINLOG_FORMAT_UNSPEC;
}
extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all)
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 0721252193d..394575191e4 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -2854,6 +2854,7 @@ public:
query_id_t first_query_id;
} binlog_evt_union;
+ mysql_cond_t COND_wsrep_thd;
/**
Internal parser state.
Note that since the parser is not re-entrant, we keep only one parser
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index af0321ce68f..fa754d2da38 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -4332,10 +4332,39 @@ bool select_create::send_eof()
*/
if (!table->s->tmp_table)
{
+#ifdef WITH_WSREP
+ /*
+ append table level exclusive key for CTAS
+ */
+ wsrep_key_arr_t key_arr= {0, 0};
+ wsrep_prepare_keys_for_isolation(thd,
+ create_table->db,
+ create_table->table_name,
+ table_list,
+ &key_arr);
+ int rcode = wsrep->append_key(
+ wsrep,
+ &thd->wsrep_ws_handle,
+ key_arr.keys, //&wkey,
+ key_arr.keys_len,
+ WSREP_KEY_EXCLUSIVE,
+ false);
+ wsrep_keys_free(&key_arr);
+ if (rcode) {
+ DBUG_PRINT("wsrep", ("row key failed: %d", rcode));
+ WSREP_ERROR("Appending table key for CTAS failed: %s, %d",
+ (wsrep_thd_query(thd)) ?
+ wsrep_thd_query(thd) : "void", rcode);
+ return true;
+ }
+ /* If commit fails, we should be able to reset the OK status. */
+ thd->get_stmt_da()->set_overwrite_status(TRUE);
+#endif /* WITH_WSREP */
trans_commit_stmt(thd);
if (!(thd->variables.option_bits & OPTION_GTID_BEGIN))
trans_commit_implicit(thd);
#ifdef WITH_WSREP
+ thd->get_stmt_da()->set_overwrite_status(FALSE);
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
if (thd->wsrep_conflict_state != NO_CONFLICT)
{
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 6fe25961e65..f60134b6162 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1053,7 +1053,7 @@ bool do_command(THD *thd)
* bail out if DB snapshot has not been installed. We however,
* allow queries "SET" and "SHOW", they are trapped later in execute_command
*/
- if (thd->variables.wsrep_on && !thd->wsrep_applier && !wsrep_ready &&
+ if (thd->variables.wsrep_on && !thd->wsrep_applier && !wsrep_ready_get() &&
command != COM_QUERY &&
command != COM_PING &&
command != COM_QUIT &&
@@ -2630,7 +2630,7 @@ mysql_execute_command(THD *thd)
We additionally allow all other commands that do not change data in
case wsrep_dirty_reads is enabled.
*/
- if (thd->variables.wsrep_on && !thd->wsrep_applier && !wsrep_ready &&
+ if (thd->variables.wsrep_on && !thd->wsrep_applier && !wsrep_ready_get() &&
lex->sql_command != SQLCOM_SET_OPTION &&
!(thd->variables.wsrep_dirty_reads &&
!is_update_query(lex->sql_command)) &&
@@ -2750,6 +2750,7 @@ mysql_execute_command(THD *thd)
{
WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
execute_show_status(thd, all_tables);
+
break;
}
case SQLCOM_SHOW_EXPLAIN:
@@ -3782,7 +3783,7 @@ end_with_restore_list:
case SQLCOM_INSERT_SELECT:
{
WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_INSERT_REPLACE);
- select_result *sel_result;
+ select_insert *sel_result;
bool explain= MY_TEST(lex->describe);
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if ((res= insert_precheck(thd, all_tables)))
@@ -4350,7 +4351,6 @@ end_with_restore_list:
if (res)
break;
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
switch (lex->sql_command) {
case SQLCOM_CREATE_EVENT:
{
@@ -4386,7 +4386,6 @@ end_with_restore_list:
lex->spname->m_name);
break;
case SQLCOM_DROP_EVENT:
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (!(res= Events::drop_event(thd,
lex->spname->m_db, lex->spname->m_name,
lex->check_exists)))
@@ -5395,7 +5394,6 @@ create_sp_error:
Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands
as specified through the thd->lex->create_view_mode flag.
*/
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
res= mysql_create_view(thd, first_table, thd->lex->create_view_mode);
break;
}
@@ -5411,7 +5409,6 @@ create_sp_error:
case SQLCOM_CREATE_TRIGGER:
{
/* Conditionally writes to binlog. */
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
res= mysql_create_or_drop_trigger(thd, all_tables, 1);
break;
@@ -5419,7 +5416,6 @@ create_sp_error:
case SQLCOM_DROP_TRIGGER:
{
/* Conditionally writes to binlog. */
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
res= mysql_create_or_drop_trigger(thd, all_tables, 0);
break;
}
@@ -5484,13 +5480,11 @@ create_sp_error:
my_ok(thd);
break;
case SQLCOM_INSTALL_PLUGIN:
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (! (res= mysql_install_plugin(thd, &thd->lex->comment,
&thd->lex->ident)))
my_ok(thd);
break;
case SQLCOM_UNINSTALL_PLUGIN:
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment,
&thd->lex->ident)))
my_ok(thd);
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index dd1f60ec078..81c47472bf9 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2005, 2017, Oracle and/or its affiliates.
- Copyright (c) 2009, 2017, SkySQL Ab.
+ Copyright (c) 2009, 2018, MariaDB
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
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 013e00faeb9..b1ffa90dd2f 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1,6 +1,6 @@
/*
- Copyright (c) 2005, 2013, Oracle and/or its affiliates.
- Copyright (c) 2010, 2017, MariaDB Corporation.
+ Copyright (c) 2005, 2018, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2018, MariaDB
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
@@ -2082,11 +2082,14 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name,
bool error;
int argc=orig_argc;
char **argv=orig_argv;
+ unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] =
+ { MYSQL_AUDIT_GENERAL_CLASSMASK };
DBUG_ENTER("mysql_install_plugin");
tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_WRITE);
if (!opt_noacl && check_table_access(thd, INSERT_ACL, &tables, FALSE, 1, FALSE))
DBUG_RETURN(TRUE);
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
/* need to open before acquiring LOCK_plugin or it will deadlock */
if (! (table = open_ltable(thd, &tables, TL_WRITE,
@@ -2120,8 +2123,7 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name,
See also mysql_uninstall_plugin() and initialize_audit_plugin()
*/
- unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] =
- { MYSQL_AUDIT_GENERAL_CLASSMASK };
+
mysql_audit_acquire_plugins(thd, event_class_mask);
mysql_mutex_lock(&LOCK_plugin);
@@ -2152,6 +2154,10 @@ err:
if (argv)
free_defaults(argv);
DBUG_RETURN(error);
+#ifdef WITH_WSREP
+ error:
+ DBUG_RETURN(TRUE);
+#endif /* WITH_WSREP */
}
@@ -2218,17 +2224,30 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name,
TABLE_LIST tables;
LEX_STRING dl= *dl_arg;
bool error= false;
+ unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] =
+ { MYSQL_AUDIT_GENERAL_CLASSMASK };
DBUG_ENTER("mysql_uninstall_plugin");
tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_WRITE);
if (!opt_noacl && check_table_access(thd, DELETE_ACL, &tables, FALSE, 1, FALSE))
DBUG_RETURN(TRUE);
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
/* need to open before acquiring LOCK_plugin or it will deadlock */
if (! (table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
DBUG_RETURN(TRUE);
+ if (!table->key_info)
+ {
+ my_printf_error(ER_UNKNOWN_ERROR,
+ "The table %s.%s has no primary key. "
+ "Please check the table definition and "
+ "create the primary key accordingly.", MYF(0),
+ table->s->db.str, table->s->table_name.str);
+ DBUG_RETURN(TRUE);
+ }
+
/*
Pre-acquire audit plugins for events that may potentially occur
during [UN]INSTALL PLUGIN.
@@ -2250,8 +2269,6 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name,
See also mysql_install_plugin() and initialize_audit_plugin()
*/
- unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] =
- { MYSQL_AUDIT_GENERAL_CLASSMASK };
mysql_audit_acquire_plugins(thd, event_class_mask);
mysql_mutex_lock(&LOCK_plugin);
@@ -2281,6 +2298,10 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name,
mysql_mutex_unlock(&LOCK_plugin);
DBUG_RETURN(error);
+#ifdef WITH_WSREP
+ error:
+ DBUG_RETURN(TRUE);
+#endif /* WITH_WSREP */
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index ba8c162b5cc..f12d982c925 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -3269,9 +3269,9 @@ void Prepared_statement::cleanup_stmt()
DBUG_ENTER("Prepared_statement::cleanup_stmt");
DBUG_PRINT("enter",("stmt: 0x%lx", (long) this));
+ thd->rollback_item_tree_changes();
cleanup_items(free_list);
thd->cleanup_after_query();
- thd->rollback_item_tree_changes();
DBUG_VOID_RETURN;
}
@@ -3880,6 +3880,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
Statement stmt_backup;
Query_arena *old_stmt_arena;
bool error= TRUE;
+ bool qc_executed= FALSE;
char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
LEX_STRING saved_cur_db_name=
@@ -4002,6 +4003,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
thd->lex->sql_command= SQLCOM_SELECT;
status_var_increment(thd->status_var.com_stat[SQLCOM_SELECT]);
thd->update_stats();
+ qc_executed= TRUE;
}
}
@@ -4040,7 +4042,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
thd->set_statement(&stmt_backup);
thd->stmt_arena= old_stmt_arena;
- if (state == Query_arena::STMT_PREPARED)
+ if (state == Query_arena::STMT_PREPARED && !qc_executed)
state= Query_arena::STMT_EXECUTED;
if (error == 0 && this->lex->sql_command == SQLCOM_CALL)
diff --git a/sql/sql_priv.h b/sql/sql_priv.h
index 2c9a22d4bd9..e659927eb7f 100644
--- a/sql/sql_priv.h
+++ b/sql/sql_priv.h
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
- Copyright (c) 2010, 2014, Monty Program Ab.
+/* Copyright (c) 2000, 2018, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2018, Monty Program Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 821badb0147..07d3bb71be6 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2016, MariaDB
+ Copyright (c) 2010, 2018, MariaDB
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
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 327b5bb0260..ec75fc2da12 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1,5 +1,6 @@
/*
Copyright (c) 2004, 2012, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2018, MariaDB
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
@@ -507,6 +508,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
if (err_status)
goto end;
}
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
/* We should have only one table in table list. */
DBUG_ASSERT(tables->next_global == 0);
@@ -611,6 +613,10 @@ end:
my_ok(thd);
DBUG_RETURN(result);
+#ifdef WITH_WSREP
+ error:
+ DBUG_RETURN(TRUE);
+#endif /* WITH_WSREP */
}
diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc
index 5182b35d80f..259f2ad78e3 100644
--- a/sql/sql_truncate.cc
+++ b/sql/sql_truncate.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates.
- Copyright (c) 2013, 2015, MariaDB
+ Copyright (c) 2012, 2018, MariaDB
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
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index a817f291abd..4a1d72d0ed7 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -689,6 +689,8 @@ int mysql_update(THD *thd,
if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
error=1; /* purecov: inspected */
select->file=tempfile; // Read row ptrs from this file
+ // select->file was copied, update self-references.
+ setup_io_cache(&select->file);
if (error >= 0)
goto err;
}
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 9fe4dd4849d..8fdd86535d1 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -429,6 +429,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
lex->link_first_table_back(view, link_to_local);
view->open_type= OT_BASE_ONLY;
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
/*
ignore lock specs for CREATE statement
@@ -686,6 +687,10 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
lex->link_first_table_back(view, link_to_local);
DBUG_RETURN(0);
+#ifdef WITH_WSREP
+ error:
+ res= TRUE;
+#endif /* WITH_WSREP */
err:
THD_STAGE_INFO(thd, stage_end);
lex->link_first_table_back(view, link_to_local);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index aea37a9d14f..0e222bf3504 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -14576,6 +14576,11 @@ option_value_no_option_type:
| '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default
{
struct sys_var_with_base tmp= $4;
+ if (tmp.var == trg_new_row_fake_var)
+ {
+ my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), "NEW");
+ MYSQL_YYABORT;
+ }
/* Lookup if necessary: must be a system variable. */
if (tmp.var == NULL)
{
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index e234d441b78..3194122f463 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -4646,7 +4646,7 @@ static Sys_var_mybool Sys_wsrep_on (
"wsrep_on", "To enable wsrep replication ",
SESSION_VAR(wsrep_on),
CMD_LINE(OPT_ARG), DEFAULT(TRUE),
- NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_has_super),
ON_UPDATE(wsrep_on_update));
static Sys_var_charptr Sys_wsrep_start_position (
@@ -4690,8 +4690,8 @@ static Sys_var_mybool Sys_wsrep_causal_reads(
static Sys_var_uint Sys_wsrep_sync_wait(
"wsrep_sync_wait", "Ensure \"synchronous\" read view before executing "
"an operation of the type specified by bitmask: 1 - READ(includes "
- "SELECT, SHOW and BEGIN/START TRANSACTION); 2 - UPDATE and DELETE; 4 - "
- "INSERT and REPLACE",
+ "SELECT and BEGIN/START TRANSACTION); 2 - UPDATE and DELETE; 4 - "
+ "INSERT and REPLACE; 8 - SHOW",
SESSION_VAR(wsrep_sync_wait), CMD_LINE(OPT_ARG),
VALID_RANGE(WSREP_SYNC_WAIT_NONE, WSREP_SYNC_WAIT_MAX),
DEFAULT(WSREP_SYNC_WAIT_NONE), BLOCK_SIZE(1),
diff --git a/sql/table.cc b/sql/table.cc
index 1ab57e6e37c..b48f5d75750 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2008, 2015, MariaDB
+/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
+ Copyright (c) 2008, 2018, MariaDB
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
@@ -3640,7 +3640,7 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
/* Whether the table definition has already been validated. */
if (table->s->table_field_def_cache == table_def)
- DBUG_RETURN(FALSE);
+ goto end;
if (table->s->fields != table_def->count)
{
@@ -3803,6 +3803,16 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
if (! error)
table->s->table_field_def_cache= table_def;
+end:
+
+ if (has_keys && !error && !table->key_info)
+ {
+ report_error(0, "Incorrect definition of table %s.%s: "
+ "indexes are missing",
+ table->s->db.str, table->alias.c_ptr());
+ error= TRUE;
+ }
+
DBUG_RETURN(error);
}
diff --git a/sql/table.h b/sql/table.h
index 69a954e73d3..73c40992751 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1,7 +1,7 @@
#ifndef TABLE_INCLUDED
#define TABLE_INCLUDED
-/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2009, 2014, SkySQL Ab.
+/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2018, MariaDB
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
@@ -511,10 +511,11 @@ typedef struct st_table_field_def
class Table_check_intact
{
protected:
+ bool has_keys;
virtual void report_error(uint code, const char *fmt, ...)= 0;
public:
- Table_check_intact() {}
+ Table_check_intact() : has_keys(FALSE) {}
virtual ~Table_check_intact() {}
/** Checks whether a table is intact. */
@@ -2224,6 +2225,7 @@ struct TABLE_LIST
DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
(alias ? alias : "<NULL>"),
get_unit()));
+ derived= get_unit();
derived_type= ((derived_type & (derived ? DTYPE_MASK : DTYPE_VIEW)) |
DTYPE_TABLE | DTYPE_MATERIALIZE);
set_check_materialized();
diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc
index a9dbc1a17c2..0a2264ac03c 100644
--- a/sql/wsrep_hton.cc
+++ b/sql/wsrep_hton.cc
@@ -119,10 +119,10 @@ void wsrep_post_commit(THD* thd, bool all)
switch (thd->wsrep_exec_mode)
{
- case LOCAL_COMMIT:
+ case LOCAL_COMMIT:
{
DBUG_ASSERT(thd->wsrep_trx_meta.gtid.seqno != WSREP_SEQNO_UNDEFINED);
- if (wsrep->post_commit(wsrep, &thd->wsrep_ws_handle))
+ if (wsrep && wsrep->post_commit(wsrep, &thd->wsrep_ws_handle))
{
DBUG_PRINT("wsrep", ("set committed fail"));
WSREP_WARN("set committed fail: %llu %d",
@@ -131,18 +131,30 @@ void wsrep_post_commit(THD* thd, bool all)
wsrep_cleanup_transaction(thd);
break;
}
- case LOCAL_STATE:
- {
- /*
- Non-InnoDB statements may have populated events in stmt cache => cleanup
- */
- WSREP_DEBUG("cleanup transaction for LOCAL_STATE: %s", thd->query());
- wsrep_cleanup_transaction(thd);
- break;
- }
- default: break;
+ case LOCAL_STATE:
+ {
+ /* non-InnoDB statements may have populated events in stmt cache
+ => cleanup
+ */
+ WSREP_DEBUG("cleanup transaction for LOCAL_STATE");
+ /*
+ Run post-rollback hook to clean up in the case if
+ some keys were populated for the transaction in provider
+ but during commit time there was no write set to replicate.
+ This may happen when client sets the SAVEPOINT and immediately
+ rolls back to savepoint after first operation.
+ */
+ if (all && thd->wsrep_conflict_state != MUST_REPLAY &&
+ wsrep && wsrep->post_rollback(wsrep, &thd->wsrep_ws_handle))
+ {
+ WSREP_WARN("post_rollback fail: %llu %d",
+ (long long)thd->thread_id, thd->get_stmt_da()->status());
+ }
+ wsrep_cleanup_transaction(thd);
+ break;
+ }
+ default: break;
}
-
}
/*
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index 49988287933..bd397a9a012 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -13,6 +13,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+#include <sql_plugin.h> // SHOW_MY_BOOL
#include <mysqld.h>
#include <sql_class.h>
#include <sql_parse.h>
@@ -205,8 +206,7 @@ wsrep_view_handler_cb (void* app_ctx,
if (memcmp(&cluster_uuid, &view->state_id.uuid, sizeof(wsrep_uuid_t)))
{
- memcpy((wsrep_uuid_t*)&cluster_uuid, &view->state_id.uuid,
- sizeof(cluster_uuid));
+ memcpy(&cluster_uuid, &view->state_id.uuid, sizeof(cluster_uuid));
wsrep_uuid_print (&cluster_uuid, cluster_uuid_str,
sizeof(cluster_uuid_str));
@@ -252,7 +252,7 @@ wsrep_view_handler_cb (void* app_ctx,
// version change
if (view->proto_ver != wsrep_protocol_version)
{
- my_bool wsrep_ready_saved= wsrep_ready;
+ my_bool wsrep_ready_saved= wsrep_ready_get();
wsrep_ready_set(FALSE);
WSREP_INFO("closing client connections for "
"protocol change %ld -> %d",
@@ -367,16 +367,34 @@ out:
return WSREP_CB_SUCCESS;
}
-void wsrep_ready_set (my_bool x)
+my_bool wsrep_ready_set (my_bool x)
{
WSREP_DEBUG("Setting wsrep_ready to %d", x);
if (mysql_mutex_lock (&LOCK_wsrep_ready)) abort();
- if (wsrep_ready != x)
+ my_bool ret= (wsrep_ready != x);
+ if (ret)
{
wsrep_ready= x;
mysql_cond_signal (&COND_wsrep_ready);
}
mysql_mutex_unlock (&LOCK_wsrep_ready);
+ return ret;
+}
+
+my_bool wsrep_ready_get (void)
+{
+ if (mysql_mutex_lock (&LOCK_wsrep_ready)) abort();
+ my_bool ret= wsrep_ready;
+ mysql_mutex_unlock (&LOCK_wsrep_ready);
+ return ret;
+}
+
+int wsrep_show_ready(THD *thd, SHOW_VAR *var, char *buff)
+{
+ var->type= SHOW_MY_BOOL;
+ var->value= buff;
+ *((my_bool *)buff)= wsrep_ready_get();
+ return 0;
}
// Wait until wsrep has reached ready state
@@ -395,17 +413,8 @@ void wsrep_ready_wait ()
static void wsrep_synced_cb(void* app_ctx)
{
WSREP_INFO("Synchronized with group, ready for connections");
- bool signal_main= false;
- if (mysql_mutex_lock (&LOCK_wsrep_ready)) abort();
- if (!wsrep_ready)
- {
- wsrep_ready= TRUE;
- mysql_cond_signal (&COND_wsrep_ready);
- signal_main= true;
-
- }
+ my_bool signal_main= wsrep_ready_set(TRUE);
local_status.set(WSREP_MEMBER_SYNCED);
- mysql_mutex_unlock (&LOCK_wsrep_ready);
if (signal_main)
{
@@ -809,6 +818,8 @@ bool wsrep_must_sync_wait (THD* thd, uint mask)
{
return (thd->variables.wsrep_sync_wait & mask) &&
thd->variables.wsrep_on &&
+ !(thd->variables.wsrep_dirty_reads &&
+ !is_update_query(thd->lex->sql_command)) &&
!thd->in_active_multi_stmt_transaction() &&
thd->wsrep_conflict_state != REPLAYING &&
thd->wsrep_sync_wait_gtid.seqno == WSREP_SEQNO_UNDEFINED;
@@ -856,17 +867,7 @@ bool wsrep_sync_wait (THD* thd, uint mask)
return false;
}
-/*
- * Helpers to deal with TOI key arrays
- */
-typedef struct wsrep_key_arr
-{
- wsrep_key_t* keys;
- size_t keys_len;
-} wsrep_key_arr_t;
-
-
-static void wsrep_keys_free(wsrep_key_arr_t* key_arr)
+void wsrep_keys_free(wsrep_key_arr_t* key_arr)
{
for (size_t i= 0; i < key_arr->keys_len; ++i)
{
@@ -931,11 +932,11 @@ static bool wsrep_prepare_key_for_isolation(const char* db,
}
/* Prepare key list from db/table and table_list */
-static bool wsrep_prepare_keys_for_isolation(THD* thd,
- const char* db,
- const char* table,
- const TABLE_LIST* table_list,
- wsrep_key_arr_t* ka)
+bool wsrep_prepare_keys_for_isolation(THD* thd,
+ const char* db,
+ const char* table,
+ const TABLE_LIST* table_list,
+ wsrep_key_arr_t* ka)
{
ka->keys= 0;
ka->keys_len= 0;
@@ -1680,7 +1681,7 @@ wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
}
else if (request_thd->lex->sql_command == SQLCOM_DROP_TABLE)
{
- WSREP_DEBUG("DROP caused BF abort");
+ WSREP_DEBUG("DROP caused BF abort, conf %d", granted_thd->wsrep_conflict_state);
ticket->wsrep_report(wsrep_debug);
mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
wsrep_abort_thd((void*)request_thd, (void*)granted_thd, 1);
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index 6dabdb66022..94c97f04aab 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -140,6 +140,7 @@ extern const char* wsrep_provider_version;
extern const char* wsrep_provider_vendor;
int wsrep_show_status(THD *thd, SHOW_VAR *var, char *buff);
+int wsrep_show_ready(THD *thd, SHOW_VAR *var, char *buff);
void wsrep_free_status(THD *thd);
int wsrep_init();
@@ -257,6 +258,7 @@ extern wsrep_seqno_t wsrep_locked_seqno;
#define WSREP_QUERY(thd) (thd->query())
+extern my_bool wsrep_ready_get();
extern void wsrep_ready_wait();
enum wsrep_trx_status {
@@ -339,4 +341,15 @@ void wsrep_init_sidno(const wsrep_uuid_t&);
bool wsrep_node_is_donor();
bool wsrep_node_is_synced();
+typedef struct wsrep_key_arr
+{
+ wsrep_key_t* keys;
+ size_t keys_len;
+} wsrep_key_arr_t;
+bool wsrep_prepare_keys_for_isolation(THD* thd,
+ const char* db,
+ const char* table,
+ const TABLE_LIST* table_list,
+ wsrep_key_arr_t* ka);
+void wsrep_keys_free(wsrep_key_arr_t* key_arr);
#endif /* WSREP_MYSQLD_H */
diff --git a/sql/wsrep_priv.h b/sql/wsrep_priv.h
index 30dce78c1a4..58d8cc4f86d 100644
--- a/sql/wsrep_priv.h
+++ b/sql/wsrep_priv.h
@@ -26,7 +26,7 @@
#include <pthread.h>
#include <cstdio>
-void wsrep_ready_set (my_bool x);
+my_bool wsrep_ready_set (my_bool x);
ssize_t wsrep_sst_prepare (void** msg);
wsrep_cb_status wsrep_sst_donate_cb (void* app_ctx,
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index ca5dcd91216..097c1ba8b41 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -1169,7 +1169,6 @@ wsrep_cb_status_t wsrep_sst_donate_cb (void* app_ctx, void* recv_ctx,
{
/* This will be reset when sync callback is called.
* Should we set wsrep_ready to FALSE here too? */
-// wsrep_notify_status(WSREP_MEMBER_DONOR);
local_status.set(WSREP_MEMBER_DONOR);
const char* method = (char*)msg;
diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc
index 307745ff1b0..328bcbd6be6 100644
--- a/sql/wsrep_thd.cc
+++ b/sql/wsrep_thd.cc
@@ -381,7 +381,7 @@ static void wsrep_replication_process(THD *thd)
case WSREP_TRX_MISSING:
/* these suggests a bug in provider code */
WSREP_WARN("bad return from recv() call: %d", rcode);
- /* fall through to node shutdown */
+ /* fall through */
case WSREP_FATAL:
/* Cluster connectivity is lost.
*
diff --git a/sql/wsrep_utils.cc b/sql/wsrep_utils.cc
index 9c5cef6a997..6b46fca33f5 100644
--- a/sql/wsrep_utils.cc
+++ b/sql/wsrep_utils.cc
@@ -264,7 +264,6 @@ process::process (const char* cmd, const char* type, char** env)
err_ = posix_spawnattr_setflags (&attr, POSIX_SPAWN_SETSIGDEF |
POSIX_SPAWN_SETSIGMASK |
- /* start a new process group */ POSIX_SPAWN_SETPGROUP |
POSIX_SPAWN_USEVFORK);
if (err_)
{