diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2018-05-07 13:49:14 +0300 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2018-05-07 13:49:14 +0300 |
commit | 648cf7176cc95f697abd8b94e860c74768680298 (patch) | |
tree | 8f3d19e0f1bd607cb515111f106715f9a4e6fcec /sql | |
parent | 7b115181987fb88b97ef6d3d88bb16bdbc281e40 (diff) | |
parent | 1ecd68d867ced1d00ebffdcedbf6bc97493f5067 (diff) | |
download | mariadb-git-648cf7176cc95f697abd8b94e860c74768680298.tar.gz |
Merge remote-tracking branch 'origin/5.5-galera' into 10.0-galera
Diffstat (limited to 'sql')
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_) { |