diff options
Diffstat (limited to 'sql')
49 files changed, 1167 insertions, 356 deletions
diff --git a/sql/create_options.cc b/sql/create_options.cc index a8d997efaf4..066adcd92e3 100644 --- a/sql/create_options.cc +++ b/sql/create_options.cc @@ -98,14 +98,13 @@ static bool report_unknown_option(THD *thd, engine_option_value *val, { DBUG_ENTER("report_unknown_option"); - if (val->parsed || suppress_warning) + if (val->parsed || suppress_warning || thd->slave_thread) { DBUG_PRINT("info", ("parsed => exiting")); DBUG_RETURN(FALSE); } - if (!(thd->variables.sql_mode & MODE_IGNORE_BAD_TABLE_OPTIONS) && - !thd->slave_thread) + if (!(thd->variables.sql_mode & MODE_IGNORE_BAD_TABLE_OPTIONS)) { my_error(ER_UNKNOWN_OPTION, MYF(0), val->name.str); DBUG_RETURN(TRUE); diff --git a/sql/field.cc b/sql/field.cc index 70598619acd..7aea222ca07 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8098,11 +8098,10 @@ uint Field_varstring::get_key_image(uchar *buff, uint length, { String val; uint local_char_length; - my_bitmap_map *old_map; - old_map= dbug_tmp_use_all_columns(table, table->read_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->read_set); val_str(&val, &val); - dbug_tmp_restore_column_map(table->read_set, old_map); + dbug_tmp_restore_column_map(&table->read_set, old_map); local_char_length= val.charpos(length / field_charset->mbmaxlen); if (local_char_length < val.length()) @@ -11396,7 +11395,7 @@ key_map Field::get_possible_keys() bool Field::validate_value_in_record_with_warn(THD *thd, const uchar *record) { - my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->read_set); bool rc; if ((rc= validate_value_in_record(thd, record))) { @@ -11408,7 +11407,7 @@ bool Field::validate_value_in_record_with_warn(THD *thd, const uchar *record) ER_THD(thd, ER_INVALID_DEFAULT_VALUE_FOR_FIELD), ErrConvString(&tmp).ptr(), field_name.str); } - dbug_tmp_restore_column_map(table->read_set, old_map); + dbug_tmp_restore_column_map(&table->read_set, old_map); return rc; } diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 609e2135a99..9313282630f 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4282,7 +4282,7 @@ int ha_partition::write_row(const uchar * buf) int error; longlong func_value; bool have_auto_increment= table->next_number_field && buf == table->record[0]; - my_bitmap_map *old_map; + MY_BITMAP *old_map; THD *thd= ha_thd(); sql_mode_t saved_sql_mode= thd->variables.sql_mode; bool saved_auto_inc_field_not_null= table->auto_increment_field_not_null; @@ -4324,9 +4324,9 @@ int ha_partition::write_row(const uchar * buf) } } - old_map= dbug_tmp_use_all_columns(table, table->read_set); + old_map= dbug_tmp_use_all_columns(table, &table->read_set); error= m_part_info->get_partition_id(m_part_info, &part_id, &func_value); - dbug_tmp_restore_column_map(table->read_set, old_map); + dbug_tmp_restore_column_map(&table->read_set, old_map); if (unlikely(error)) { m_part_info->err_value= func_value; @@ -11326,13 +11326,12 @@ int ha_partition::bulk_update_row(const uchar *old_data, const uchar *new_data, int error= 0; uint32 part_id; longlong func_value; - my_bitmap_map *old_map; DBUG_ENTER("ha_partition::bulk_update_row"); - old_map= dbug_tmp_use_all_columns(table, table->read_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->read_set); error= m_part_info->get_partition_id(m_part_info, &part_id, &func_value); - dbug_tmp_restore_column_map(table->read_set, old_map); + dbug_tmp_restore_column_map(&table->read_set, old_map); if (unlikely(error)) { m_part_info->err_value= func_value; diff --git a/sql/handler.cc b/sql/handler.cc index 34fc2ad7e67..98f651971c3 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -859,9 +859,11 @@ static my_bool kill_handlerton(THD *thd, plugin_ref plugin, { handlerton *hton= plugin_hton(plugin); + mysql_mutex_lock(&thd->LOCK_thd_data); if (hton->state == SHOW_OPTION_YES && hton->kill_query && thd_get_ha_data(thd, hton)) hton->kill_query(hton, thd, *(enum thd_kill_levels *) level); + mysql_mutex_unlock(&thd->LOCK_thd_data); return FALSE; } @@ -5211,6 +5213,7 @@ int ha_create_table(THD *thd, const char *path, char name_buff[FN_REFLEN]; const char *name; TABLE_SHARE share; + Abort_on_warning_instant_set old_abort_on_warning(thd, 0); bool temp_table __attribute__((unused)) = create_info->options & (HA_LEX_CREATE_TMP_TABLE | HA_CREATE_TMP_ALTER); DBUG_ENTER("ha_create_table"); diff --git a/sql/handler.h b/sql/handler.h index 5dd3f6f5c5e..85da8bc4c22 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1507,7 +1507,7 @@ struct handlerton enum handler_create_iterator_result (*create_iterator)(handlerton *hton, enum handler_iterator_type type, struct handler_iterator *fill_this_in); - int (*abort_transaction)(handlerton *hton, THD *bf_thd, + void (*abort_transaction)(handlerton *hton, THD *bf_thd, THD *victim_thd, my_bool signal); int (*set_checkpoint)(handlerton *hton, const XID* xid); int (*get_checkpoint)(handlerton *hton, XID* xid); diff --git a/sql/item.cc b/sql/item.cc index f700bcfe680..1228b37f144 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1423,9 +1423,9 @@ int Item::save_in_field_no_warnings(Field *field, bool no_conversions) Sql_mode_save sql_mode(thd); thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE); thd->variables.sql_mode|= MODE_INVALID_DATES; - my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set); res= save_in_field(field, no_conversions); - dbug_tmp_restore_column_map(table->write_set, old_map); + dbug_tmp_restore_column_map(&table->write_set, old_map); return res; } @@ -5753,7 +5753,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) Field *from_field= (Field *)not_found_field; bool outer_fixed= false; SELECT_LEX *select= thd->lex->current_select; - + if (select && select->in_tvc) { my_error(ER_FIELD_REFERENCE_IN_TVC, MYF(0), full_name()); @@ -6652,7 +6652,7 @@ Item *Item_string::make_odbc_literal(THD *thd, const LEX_CSTRING *typestr) } -static int save_int_value_in_field (Field *field, longlong nr, +static int save_int_value_in_field (Field *field, longlong nr, bool null_value, bool unsigned_flag) { if (null_value) @@ -8427,6 +8427,22 @@ bool Item_direct_ref::val_native(THD *thd, Native *to) } +longlong Item_direct_ref::val_time_packed() +{ + longlong tmp = (*ref)->val_time_packed(); + null_value= (*ref)->null_value; + return tmp; +} + + +longlong Item_direct_ref::val_datetime_packed() +{ + longlong tmp = (*ref)->val_datetime_packed(); + null_value= (*ref)->null_value; + return tmp; +} + + Item_cache_wrapper::~Item_cache_wrapper() { DBUG_ASSERT(expr_cache == 0); diff --git a/sql/item.h b/sql/item.h index e2e18ce9b86..b960dfe6871 100644 --- a/sql/item.h +++ b/sql/item.h @@ -5569,14 +5569,17 @@ public: return Item_ref::fix_fields(thd, it); } void save_val(Field *to); + /* Below we should have all val() methods as in Item_ref */ double val_real(); longlong val_int(); - String *val_str(String* tmp); bool val_native(THD *thd, Native *to); my_decimal *val_decimal(my_decimal *); bool val_bool(); + String *val_str(String* tmp); bool is_null(); bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate); + longlong val_datetime_packed(); + longlong val_time_packed(); virtual Ref_Type ref_type() { return DIRECT_REF; } Item *get_copy(THD *thd) { return get_item_copy<Item_direct_ref>(thd, this); } @@ -5905,6 +5908,20 @@ public: } return Item_direct_ref::get_date(thd, ltime, fuzzydate); } + longlong val_time_packed() + { + if (check_null_ref()) + return 0; + else + return Item_direct_ref::val_time_packed(); + } + longlong val_datetime_packed() + { + if (check_null_ref()) + return 0; + else + return Item_direct_ref::val_datetime_packed(); + } bool send(Protocol *protocol, st_value *buffer); void save_org_in_field(Field *field, fast_field_copier data __attribute__ ((__unused__))) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 4f878d8437c..bbd5fbf073a 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -321,13 +321,13 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item, TABLE *table= field->table; Sql_mode_save sql_mode(thd); Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE); - my_bitmap_map *old_maps[2] = { NULL, NULL }; + MY_BITMAP *old_maps[2] = { NULL, NULL }; ulonglong UNINIT_VAR(orig_field_val); /* original field value if valid */ /* table->read_set may not be set if we come here from a CREATE TABLE */ if (table && table->read_set) dbug_tmp_use_all_columns(table, old_maps, - table->read_set, table->write_set); + &table->read_set, &table->write_set); /* For comparison purposes allow invalid dates like 2000-01-32 */ thd->variables.sql_mode= (thd->variables.sql_mode & ~MODE_NO_ZERO_DATE) | MODE_INVALID_DATES; @@ -368,7 +368,7 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item, DBUG_ASSERT(!result); } if (table && table->read_set) - dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_maps); + dbug_tmp_restore_column_maps(&table->read_set, &table->write_set, old_maps); } return result; } @@ -1198,9 +1198,9 @@ longlong Item_func_truth::val_int() bool Item_in_optimizer::is_top_level_item() { - if (invisible_mode()) - return FALSE; - return ((Item_in_subselect *)args[1])->is_top_level_item(); + if (!invisible_mode()) + return ((Item_in_subselect *)args[1])->is_top_level_item(); + return false; } @@ -3196,7 +3196,7 @@ bool Item_func_decode_oracle::fix_length_and_dec() /* Aggregate all THEN and ELSE expression types and collations when string result - + @param THD - current thd @param start - an element in args to start aggregating from */ diff --git a/sql/key.cc b/sql/key.cc index adff6975631..6f0a1112497 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -244,14 +244,13 @@ void key_restore(uchar *to_record, const uchar *from_key, KEY *key_info, else if (key_part->key_part_flag & HA_VAR_LENGTH_PART) { Field *field= key_part->field; - my_bitmap_map *old_map; my_ptrdiff_t ptrdiff= to_record - field->table->record[0]; field->move_field_offset(ptrdiff); key_length-= HA_KEY_BLOB_LENGTH; length= MY_MIN(key_length, key_part->length); - old_map= dbug_tmp_use_all_columns(field->table, field->table->write_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(field->table, &field->table->write_set); field->set_key_image(from_key, length); - dbug_tmp_restore_column_map(field->table->write_set, old_map); + dbug_tmp_restore_column_map(&field->table->write_set, old_map); from_key+= HA_KEY_BLOB_LENGTH; field->move_field_offset(-ptrdiff); } @@ -419,7 +418,7 @@ void field_unpack(String *to, Field *field, const uchar *rec, uint max_length, void key_unpack(String *to, TABLE *table, KEY *key) { - my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->read_set); DBUG_ENTER("key_unpack"); to->length(0); @@ -443,7 +442,7 @@ void key_unpack(String *to, TABLE *table, KEY *key) field_unpack(to, key_part->field, table->record[0], key_part->length, MY_TEST(key_part->key_part_flag & HA_PART_KEY_SEG)); } - dbug_tmp_restore_column_map(table->read_set, old_map); + dbug_tmp_restore_column_map(&table->read_set, old_map); DBUG_VOID_RETURN; } diff --git a/sql/log_event.cc b/sql/log_event.cc index 20a41dc8aee..52995cc7e66 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -13741,11 +13741,11 @@ int Rows_log_event::update_sequence() /* This event come from a setval function executed on the master. Update the sequence next_number and round, like we do with setval() */ - my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, - table->read_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, + &table->read_set); longlong nextval= table->field[NEXT_FIELD_NO]->val_int(); longlong round= table->field[ROUND_FIELD_NO]->val_int(); - dbug_tmp_restore_column_map(table->read_set, old_map); + dbug_tmp_restore_column_map(&table->read_set, old_map); return table->s->sequence->set_value(table, nextval, round, 0) > 0; } diff --git a/sql/mdl.cc b/sql/mdl.cc index 93b7982c4a5..bea02f2bf6a 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -1138,7 +1138,7 @@ MDL_wait::timed_wait(MDL_context_owner *owner, struct timespec *abs_timeout, DBUG_ASSERT(!debug_sync_set_action((owner->get_thd()), STRING_WITH_LEN(act))); };); - if (wsrep_thd_is_BF(owner->get_thd(), false)) + if (WSREP_ON && wsrep_thd_is_BF(owner->get_thd(), false)) { wait_result= mysql_cond_wait(&m_COND_wait_status, &m_LOCK_wait_status); } @@ -1211,7 +1211,7 @@ void MDL_lock::Ticket_list::add_ticket(MDL_ticket *ticket) */ DBUG_ASSERT(ticket->get_lock()); #ifdef WITH_WSREP - if ((this == &(ticket->get_lock()->m_waiting)) && + if (WSREP_ON && (this == &(ticket->get_lock()->m_waiting)) && wsrep_thd_is_BF(ticket->get_ctx()->get_thd(), false)) { Ticket_iterator itw(ticket->get_lock()->m_waiting); @@ -1762,7 +1762,7 @@ MDL_lock::can_grant_lock(enum_mdl_type type_arg, non WSREP threads must report conflict immediately note: RSU processing wsrep threads, have wsrep_on==OFF */ - if (WSREP(requestor_ctx->get_thd()) || + if (WSREP_ON && WSREP(requestor_ctx->get_thd()) || requestor_ctx->get_thd()->wsrep_cs().mode() == wsrep::client_state::m_rsu) { diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a74fb4326e4..ffdbadbe129 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -363,7 +363,6 @@ static bool binlog_format_used= false; LEX_STRING opt_init_connect, opt_init_slave; mysql_cond_t COND_thread_cache; static mysql_cond_t COND_flush_thread_cache; -mysql_cond_t COND_slave_background; static DYNAMIC_ARRAY all_options; static longlong start_memory_used; @@ -701,7 +700,7 @@ mysql_mutex_t LOCK_crypt, LOCK_global_system_variables, LOCK_user_conn, - LOCK_connection_count, LOCK_error_messages, LOCK_slave_background; + LOCK_connection_count, LOCK_error_messages; mysql_mutex_t LOCK_stats, LOCK_global_user_client_stats, LOCK_global_table_stats, LOCK_global_index_stats; @@ -893,8 +892,7 @@ PSI_mutex_key key_LOCK_stats, PSI_mutex_key key_LOCK_gtid_waiting; PSI_mutex_key key_LOCK_after_binlog_sync; -PSI_mutex_key key_LOCK_prepare_ordered, key_LOCK_commit_ordered, - key_LOCK_slave_background; +PSI_mutex_key key_LOCK_prepare_ordered, key_LOCK_commit_ordered; PSI_mutex_key key_TABLE_SHARE_LOCK_share; PSI_mutex_key key_LOCK_ack_receiver; @@ -968,7 +966,6 @@ static PSI_mutex_info all_server_mutexes[]= { &key_LOCK_prepare_ordered, "LOCK_prepare_ordered", PSI_FLAG_GLOBAL}, { &key_LOCK_after_binlog_sync, "LOCK_after_binlog_sync", PSI_FLAG_GLOBAL}, { &key_LOCK_commit_ordered, "LOCK_commit_ordered", PSI_FLAG_GLOBAL}, - { &key_LOCK_slave_background, "LOCK_slave_background", PSI_FLAG_GLOBAL}, { &key_LOCK_thread_cache, "LOCK_thread_cache", PSI_FLAG_GLOBAL}, { &key_PARTITION_LOCK_auto_inc, "HA_DATA_PARTITION::LOCK_auto_inc", 0}, { &key_LOCK_slave_state, "LOCK_slave_state", 0}, @@ -1039,7 +1036,7 @@ PSI_cond_key key_TC_LOG_MMAP_COND_queue_busy; PSI_cond_key key_COND_rpl_thread_queue, key_COND_rpl_thread, key_COND_rpl_thread_stop, key_COND_rpl_thread_pool, key_COND_parallel_entry, key_COND_group_commit_orderer, - key_COND_prepare_ordered, key_COND_slave_background; + key_COND_prepare_ordered; PSI_cond_key key_COND_wait_gtid, key_COND_gtid_ignore_duplicates; PSI_cond_key key_COND_ack_receiver; @@ -1087,7 +1084,6 @@ static PSI_cond_info all_server_conds[]= { &key_COND_parallel_entry, "COND_parallel_entry", 0}, { &key_COND_group_commit_orderer, "COND_group_commit_orderer", 0}, { &key_COND_prepare_ordered, "COND_prepare_ordered", 0}, - { &key_COND_slave_background, "COND_slave_background", 0}, { &key_COND_start_thread, "COND_start_thread", PSI_FLAG_GLOBAL}, { &key_COND_wait_gtid, "COND_wait_gtid", 0}, { &key_COND_gtid_ignore_duplicates, "COND_gtid_ignore_duplicates", 0}, @@ -1792,6 +1788,7 @@ static void close_connections(void) { wsrep_deinit(true); } + wsrep_sst_auth_free(); #endif /* All threads has now been aborted */ DBUG_PRINT("quit", ("Waiting for threads to die (count=%u)", @@ -1905,6 +1902,7 @@ extern "C" void unireg_abort(int exit_code) wsrep_deinit(true); wsrep_deinit_server(); } + wsrep_sst_auth_free(); #endif // WITH_WSREP clean_up(!opt_abort && (exit_code || !opt_bootstrap)); /* purecov: inspected */ @@ -2140,8 +2138,6 @@ static void clean_up_mutexes() mysql_cond_destroy(&COND_prepare_ordered); mysql_mutex_destroy(&LOCK_after_binlog_sync); mysql_mutex_destroy(&LOCK_commit_ordered); - mysql_mutex_destroy(&LOCK_slave_background); - mysql_cond_destroy(&COND_slave_background); #ifndef EMBEDDED_LIBRARY mysql_mutex_destroy(&LOCK_error_log); #endif @@ -4555,9 +4551,6 @@ static int init_thread_environment() MY_MUTEX_INIT_SLOW); mysql_mutex_init(key_LOCK_commit_ordered, &LOCK_commit_ordered, MY_MUTEX_INIT_SLOW); - mysql_mutex_init(key_LOCK_slave_background, &LOCK_slave_background, - MY_MUTEX_INIT_SLOW); - mysql_cond_init(key_COND_slave_background, &COND_slave_background, NULL); #ifdef HAVE_OPENSSL mysql_mutex_init(key_LOCK_des_key_file, @@ -5255,6 +5248,10 @@ static int init_server_components() that there are unprocessed options. */ my_getopt_skip_unknown= 0; +#ifdef WITH_WSREP + if (wsrep_recovery) + my_getopt_skip_unknown= TRUE; +#endif if ((ho_error= handle_options(&remaining_argc, &remaining_argv, no_opts, mysqld_get_one_option))) @@ -5264,20 +5261,27 @@ static int init_server_components() remaining_argv--; my_getopt_skip_unknown= TRUE; - if (remaining_argc > 1) +#ifdef WITH_WSREP + if (!wsrep_recovery) { - fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n", - my_progname, remaining_argv[1]); - unireg_abort(1); +#endif + if (remaining_argc > 1) + { + fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n", + my_progname, remaining_argv[1]); + unireg_abort(1); + } +#ifdef WITH_WSREP } +#endif } - if (init_io_cache_encryption()) - unireg_abort(1); - if (opt_abort) unireg_abort(0); + if (init_io_cache_encryption()) + unireg_abort(1); + /* if the errmsg.sys is not loaded, terminate to maintain behaviour */ if (!DEFAULT_ERRMSGS[0][0]) unireg_abort(1); diff --git a/sql/mysqld.h b/sql/mysqld.h index bd45ff7b798..c1469caced5 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -615,8 +615,7 @@ extern mysql_mutex_t LOCK_error_log, LOCK_delayed_insert, LOCK_short_uuid_generator, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, LOCK_active_mi, LOCK_manager, LOCK_user_conn, - LOCK_prepared_stmt_count, LOCK_error_messages, LOCK_connection_count, - LOCK_slave_background; + LOCK_prepared_stmt_count, LOCK_error_messages, LOCK_connection_count; extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_global_system_variables; extern mysql_rwlock_t LOCK_all_status_vars; extern mysql_mutex_t LOCK_start_thread; @@ -631,7 +630,6 @@ extern mysql_rwlock_t LOCK_ssl_refresh; extern mysql_prlock_t LOCK_system_variables_hash; extern mysql_cond_t COND_start_thread; extern mysql_cond_t COND_manager; -extern mysql_cond_t COND_slave_background; extern Atomic_counter<uint32_t> thread_count; extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher, diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 97ebbdbe8a7..8451fb87994 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3636,8 +3636,7 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond) void store_key_image_to_rec(Field *field, uchar *ptr, uint len) { - /* Do the same as print_key() does */ - my_bitmap_map *old_map; + /* Do the same as print_key() does */ if (field->real_maybe_null()) { @@ -3649,10 +3648,10 @@ void store_key_image_to_rec(Field *field, uchar *ptr, uint len) field->set_notnull(); ptr++; } - old_map= dbug_tmp_use_all_columns(field->table, - field->table->write_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(field->table, + &field->table->write_set); field->set_key_image(ptr, len); - dbug_tmp_restore_column_map(field->table->write_set, old_map); + dbug_tmp_restore_column_map(&field->table->write_set, old_map); } #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -3867,7 +3866,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond) PART_PRUNE_PARAM prune_param; MEM_ROOT alloc; RANGE_OPT_PARAM *range_par= &prune_param.range_param; - my_bitmap_map *old_sets[2]; + MY_BITMAP *old_sets[2]; prune_param.part_info= part_info; init_sql_alloc(&alloc, "prune_partitions", @@ -3884,7 +3883,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond) } dbug_tmp_use_all_columns(table, old_sets, - table->read_set, table->write_set); + &table->read_set, &table->write_set); range_par->thd= thd; range_par->table= table; /* range_par->cond doesn't need initialization */ @@ -3981,7 +3980,7 @@ all_used: retval= FALSE; // some partitions are used mark_all_partitions_as_used(prune_param.part_info); end: - dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets); + dbug_tmp_restore_column_maps(&table->read_set, &table->write_set, old_sets); thd->no_errors=0; thd->mem_root= range_par->old_root; free_root(&alloc,MYF(0)); // Return memory & allocator @@ -11122,6 +11121,7 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, uint keynr= param->real_keynr[idx]; DBUG_ENTER("check_quick_select"); + param->is_ror_scan= FALSE; /* Handle cases when we don't have a valid non-empty list of range */ if (!tree) DBUG_RETURN(HA_POS_ERROR); @@ -15658,8 +15658,8 @@ static void print_sel_arg_key(Field *field, const uchar *key, String *out) { TABLE *table= field->table; - my_bitmap_map *old_sets[2]; - dbug_tmp_use_all_columns(table, old_sets, table->read_set, table->write_set); + MY_BITMAP *old_sets[2]; + dbug_tmp_use_all_columns(table, old_sets, &table->read_set, &table->write_set); if (field->real_maybe_null()) { @@ -15679,7 +15679,7 @@ print_sel_arg_key(Field *field, const uchar *key, String *out) field->val_str(out); end: - dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets); + dbug_tmp_restore_column_maps(&table->read_set, &table->write_set, old_sets); } @@ -15774,9 +15774,9 @@ print_key(KEY_PART *key_part, const uchar *key, uint used_length) const uchar *key_end= key+used_length; uint store_length; TABLE *table= key_part->field->table; - my_bitmap_map *old_sets[2]; + MY_BITMAP *old_sets[2]; - dbug_tmp_use_all_columns(table, old_sets, table->read_set, table->write_set); + dbug_tmp_use_all_columns(table, old_sets, &table->read_set, &table->write_set); for (; key < key_end; key+=store_length, key_part++) { @@ -15803,7 +15803,7 @@ print_key(KEY_PART *key_part, const uchar *key, uint used_length) if (key+store_length < key_end) fputc('/',DBUG_FILE); } - dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets); + dbug_tmp_restore_column_maps(&table->read_set, &table->write_set, old_sets); } @@ -15811,16 +15811,16 @@ static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg) { char buf[MAX_KEY/8+1]; TABLE *table; - my_bitmap_map *old_sets[2]; + MY_BITMAP *old_sets[2]; DBUG_ENTER("print_quick"); if (!quick) DBUG_VOID_RETURN; DBUG_LOCK_FILE; table= quick->head; - dbug_tmp_use_all_columns(table, old_sets, table->read_set, table->write_set); + dbug_tmp_use_all_columns(table, old_sets, &table->read_set, &table->write_set); quick->dbug_dump(0, TRUE); - dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets); + dbug_tmp_restore_column_maps(&table->read_set, &table->write_set, old_sets); fprintf(DBUG_FILE,"other_keys: 0x%s:\n", needed_reg->print(buf)); diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 9f08964e62c..a8459438be7 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -1449,13 +1449,13 @@ void partition_info::print_no_partition_found(TABLE *table_arg, myf errflag) buf_ptr= (char*)"from column_list"; else { - my_bitmap_map *old_map= dbug_tmp_use_all_columns(table_arg, table_arg->read_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(table_arg, &table_arg->read_set); if (part_expr->null_value) buf_ptr= (char*)"NULL"; else longlong10_to_str(err_value, buf, part_expr->unsigned_flag ? 10 : -10); - dbug_tmp_restore_column_map(table_arg->read_set, old_map); + dbug_tmp_restore_column_map(&table_arg->read_set, old_map); } my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, errflag, buf_ptr); } diff --git a/sql/protocol.cc b/sql/protocol.cc index aa9651e974c..eb7f19d2bd0 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -1269,15 +1269,15 @@ bool Protocol_text::store(Field *field) CHARSET_INFO *tocs= this->thd->variables.character_set_results; #ifdef DBUG_ASSERT_EXISTS TABLE *table= field->table; - my_bitmap_map *old_map= 0; + MY_BITMAP *old_map= 0; if (table->file) - old_map= dbug_tmp_use_all_columns(table, table->read_set); + old_map= dbug_tmp_use_all_columns(table, &table->read_set); #endif field->val_str(&str); #ifdef DBUG_ASSERT_EXISTS if (old_map) - dbug_tmp_restore_column_map(table->read_set, old_map); + dbug_tmp_restore_column_map(&table->read_set, old_map); #endif return store_string_aux(str.ptr(), str.length(), str.charset(), tocs); diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index 154636480ca..0ac1533519f 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -8,6 +8,7 @@ #ifdef WITH_WSREP #include "wsrep_trans_observer.h" #endif +#include "sql_repl.h" /* Code for optional parallel execution of replicated events on the slave. @@ -100,7 +101,7 @@ handle_queued_pos_update(THD *thd, rpl_parallel_thread::queued_event *qev) return; mysql_mutex_lock(&rli->data_lock); - cmp= strcmp(rli->group_relay_log_name, qev->event_relay_log_name); + cmp= compare_log_name(rli->group_relay_log_name, qev->event_relay_log_name); if (cmp < 0) { rli->group_relay_log_pos= qev->future_event_relay_log_pos; @@ -109,7 +110,7 @@ handle_queued_pos_update(THD *thd, rpl_parallel_thread::queued_event *qev) rli->group_relay_log_pos < qev->future_event_relay_log_pos) rli->group_relay_log_pos= qev->future_event_relay_log_pos; - cmp= strcmp(rli->group_master_log_name, qev->future_event_master_log_name); + cmp= compare_log_name(rli->group_master_log_name, qev->future_event_master_log_name); if (cmp < 0) { strcpy(rli->group_master_log_name, qev->future_event_master_log_name); diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index bcdff1e33a8..c8f77acf523 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -991,7 +991,7 @@ void Relay_log_info::inc_group_relay_log_pos(ulonglong log_pos, if (rgi->is_parallel_exec) { /* In case of parallel replication, do not update the position backwards. */ - int cmp= strcmp(group_relay_log_name, rgi->event_relay_log_name); + int cmp= compare_log_name(group_relay_log_name, rgi->event_relay_log_name); if (cmp < 0) { group_relay_log_pos= rgi->future_event_relay_log_pos; @@ -1003,7 +1003,7 @@ void Relay_log_info::inc_group_relay_log_pos(ulonglong log_pos, In the parallel case we need to update the master_log_name here, rather than in Rotate_log_event::do_update_pos(). */ - cmp= strcmp(group_master_log_name, rgi->future_event_master_log_name); + cmp= compare_log_name(group_master_log_name, rgi->future_event_master_log_name); if (cmp <= 0) { if (cmp < 0) diff --git a/sql/slave.cc b/sql/slave.cc index 9d4049c6452..7e261dc0233 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -64,6 +64,7 @@ #include "rpl_parallel.h" #include "sql_show.h" #include "semisync_slave.h" +#include "sql_manager.h" #define FLAGSTR(V,F) ((V)&(F)?#F" ":"") @@ -363,9 +364,9 @@ end: } -static void -handle_gtid_pos_auto_create_request(THD *thd, void *hton) +static void bg_gtid_pos_auto_create(void *hton) { + THD *thd= NULL; int UNINIT_VAR(err); plugin_ref engine= NULL, *auto_engines; rpl_slave_state::gtid_pos_table *entry; @@ -377,7 +378,6 @@ handle_gtid_pos_auto_create_request(THD *thd, void *hton) it. */ mysql_mutex_lock(&LOCK_global_system_variables); - engine= NULL; for (auto_engines= opt_gtid_pos_auto_plugins; auto_engines && *auto_engines; ++auto_engines) @@ -422,6 +422,13 @@ handle_gtid_pos_auto_create_request(THD *thd, void *hton) table_name.str= loc_table_name.c_ptr_safe(); table_name.length= loc_table_name.length(); + thd= new THD(next_thread_id()); + thd->thread_stack= (char*) &thd; /* Set approximate stack start */ + thd->system_thread = SYSTEM_THREAD_SLAVE_BACKGROUND; + thd->store_globals(); + thd->security_ctx->skip_grants(); + thd->set_command(COM_DAEMON); + thd->variables.wsrep_on= 0; err= gtid_pos_table_creation(thd, engine, &table_name); if (err) { @@ -449,15 +456,15 @@ handle_gtid_pos_auto_create_request(THD *thd, void *hton) mysql_mutex_unlock(&rpl_global_gtid_slave_state->LOCK_slave_state); end: + delete thd; if (engine) plugin_unlock(NULL, engine); } -static bool slave_background_thread_running; -static bool slave_background_thread_stop; static bool slave_background_thread_gtid_loaded; +<<<<<<< HEAD static struct slave_background_kill_t { slave_background_kill_t *next; THD *to_kill; @@ -473,21 +480,31 @@ static volatile bool slave_background_gtid_pending_delete_flag; pthread_handler_t handle_slave_background(void *arg __attribute__((unused))) -{ - THD *thd; - PSI_stage_info old_stage; - bool stop; +||||||| 75538f94ca0 +static struct slave_background_kill_t { + slave_background_kill_t *next; + THD *to_kill; +} *slave_background_kill_list; - my_thread_init(); - thd= new THD(next_thread_id()); +static struct slave_background_gtid_pos_create_t { + slave_background_gtid_pos_create_t *next; + void *hton; +} *slave_background_gtid_pos_create_list; + + +pthread_handler_t +handle_slave_background(void *arg __attribute__((unused))) +======= +static void bg_rpl_load_gtid_slave_state(void *) +>>>>>>> bb-10.3-release +{ + THD *thd= new THD(next_thread_id()); thd->thread_stack= (char*) &thd; /* Set approximate stack start */ thd->system_thread = SYSTEM_THREAD_SLAVE_BACKGROUND; thd->store_globals(); thd->security_ctx->skip_grants(); thd->set_command(COM_DAEMON); -#ifdef WITH_WSREP thd->variables.wsrep_on= 0; -#endif thd_proc_info(thd, "Loading slave GTID position from table"); if (rpl_load_gtid_slave_state(thd)) @@ -497,8 +514,10 @@ handle_slave_background(void *arg __attribute__((unused))) thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message()); - mysql_mutex_lock(&LOCK_slave_background); + // hijacking global_rpl_thread_pool cond here - it's only once on startup + mysql_mutex_lock(&global_rpl_thread_pool.LOCK_rpl_thread_pool); slave_background_thread_gtid_loaded= true; +<<<<<<< HEAD mysql_cond_broadcast(&COND_slave_background); THD_STAGE_INFO(thd, stage_slave_background_process_request); @@ -569,35 +588,100 @@ handle_slave_background(void *arg __attribute__((unused))) mysql_cond_broadcast(&COND_slave_background); mysql_mutex_unlock(&LOCK_slave_background); +||||||| 75538f94ca0 + mysql_cond_broadcast(&COND_slave_background); + + THD_STAGE_INFO(thd, stage_slave_background_process_request); + do + { + slave_background_kill_t *kill_list; + slave_background_gtid_pos_create_t *create_list; + + thd->ENTER_COND(&COND_slave_background, &LOCK_slave_background, + &stage_slave_background_wait_request, + &old_stage); + for (;;) + { + stop= abort_loop || thd->killed || slave_background_thread_stop; + kill_list= slave_background_kill_list; + create_list= slave_background_gtid_pos_create_list; + if (stop || kill_list || create_list) + break; + mysql_cond_wait(&COND_slave_background, &LOCK_slave_background); + } + + slave_background_kill_list= NULL; + slave_background_gtid_pos_create_list= NULL; + thd->EXIT_COND(&old_stage); + + while (kill_list) + { + slave_background_kill_t *p = kill_list; + THD *to_kill= p->to_kill; + kill_list= p->next; + + to_kill->awake(KILL_CONNECTION); + mysql_mutex_lock(&to_kill->LOCK_wakeup_ready); + to_kill->rgi_slave->killed_for_retry= + rpl_group_info::RETRY_KILL_KILLED; + mysql_cond_broadcast(&to_kill->COND_wakeup_ready); + mysql_mutex_unlock(&to_kill->LOCK_wakeup_ready); + my_free(p); + } + + while (create_list) + { + slave_background_gtid_pos_create_t *next= create_list->next; + void *hton= create_list->hton; + handle_gtid_pos_auto_create_request(thd, hton); + my_free(create_list); + create_list= next; + } + + mysql_mutex_lock(&LOCK_slave_background); + } while (!stop); + + slave_background_thread_running= false; + mysql_cond_broadcast(&COND_slave_background); + mysql_mutex_unlock(&LOCK_slave_background); + +======= + mysql_cond_signal(&global_rpl_thread_pool.COND_rpl_thread_pool); + mysql_mutex_unlock(&global_rpl_thread_pool.LOCK_rpl_thread_pool); +>>>>>>> bb-10.3-release delete thd; +<<<<<<< HEAD my_thread_end(); return 0; -} +||||||| 75538f94ca0 + thread_safe_decrement32(&service_thread_count); + signal_thd_deleted(); + my_thread_end(); + return 0; +======= +>>>>>>> bb-10.3-release +} +static void bg_slave_kill(void *victim) +{ + THD *to_kill= (THD *)victim; + to_kill->awake(KILL_CONNECTION); + mysql_mutex_lock(&to_kill->LOCK_wakeup_ready); + to_kill->rgi_slave->killed_for_retry= rpl_group_info::RETRY_KILL_KILLED; + mysql_cond_broadcast(&to_kill->COND_wakeup_ready); + mysql_mutex_unlock(&to_kill->LOCK_wakeup_ready); +} -void -slave_background_kill_request(THD *to_kill) +void slave_background_kill_request(THD *to_kill) { if (to_kill->rgi_slave->killed_for_retry) return; // Already deadlock killed. - slave_background_kill_t *p= - (slave_background_kill_t *)my_malloc(sizeof(*p), MYF(MY_WME)); - if (p) - { - p->to_kill= to_kill; - to_kill->rgi_slave->killed_for_retry= - rpl_group_info::RETRY_KILL_PENDING; - mysql_mutex_lock(&LOCK_slave_background); - p->next= slave_background_kill_list; - slave_background_kill_list= p; - mysql_cond_signal(&COND_slave_background); - mysql_mutex_unlock(&LOCK_slave_background); - } + to_kill->rgi_slave->killed_for_retry= rpl_group_info::RETRY_KILL_PENDING; + mysql_manager_submit(bg_slave_kill, to_kill); } - /* This function must only be called from a slave SQL thread (or worker thread), to ensure that the table_entry will not go away before we can lock the @@ -607,23 +691,18 @@ void slave_background_gtid_pos_create_request( rpl_slave_state::gtid_pos_table *table_entry) { - slave_background_gtid_pos_create_t *p; - if (table_entry->state != rpl_slave_state::GTID_POS_AUTO_CREATE) return; - p= (slave_background_gtid_pos_create_t *)my_malloc(sizeof(*p), MYF(MY_WME)); - if (!p) - return; mysql_mutex_lock(&rpl_global_gtid_slave_state->LOCK_slave_state); if (table_entry->state != rpl_slave_state::GTID_POS_AUTO_CREATE) { - my_free(p); mysql_mutex_unlock(&rpl_global_gtid_slave_state->LOCK_slave_state); return; } table_entry->state= rpl_slave_state::GTID_POS_CREATE_REQUESTED; mysql_mutex_unlock(&rpl_global_gtid_slave_state->LOCK_slave_state); +<<<<<<< HEAD p->hton= table_entry->table_hton; mysql_mutex_lock(&LOCK_slave_background); p->next= slave_background_gtid_pos_create_list; @@ -698,6 +777,67 @@ stop_slave_background_thread() while (slave_background_thread_running) mysql_cond_wait(&COND_slave_background, &LOCK_slave_background); mysql_mutex_unlock(&LOCK_slave_background); +||||||| 75538f94ca0 + p->hton= table_entry->table_hton; + mysql_mutex_lock(&LOCK_slave_background); + p->next= slave_background_gtid_pos_create_list; + slave_background_gtid_pos_create_list= p; + mysql_cond_signal(&COND_slave_background); + mysql_mutex_unlock(&LOCK_slave_background); +} + + +/* + Start the slave background thread. + + This thread is currently used for two purposes: + + 1. To load the GTID state from mysql.gtid_slave_pos at server start; reading + from table requires valid THD, which is otherwise not available during + server init. + + 2. To kill worker thread transactions during parallel replication, when a + storage engine attempts to take an errorneous conflicting lock that would + cause a deadlock. Killing is done asynchroneously, as the kill may not + be safe within the context of a callback from inside storage engine + locking code. +*/ +static int +start_slave_background_thread() +{ + pthread_t th; + + slave_background_thread_running= true; + slave_background_thread_stop= false; + slave_background_thread_gtid_loaded= false; + if (mysql_thread_create(key_thread_slave_background, + &th, &connection_attrib, handle_slave_background, + NULL)) + { + sql_print_error("Failed to create thread while initialising slave"); + return 1; + } + mysql_mutex_lock(&LOCK_slave_background); + while (!slave_background_thread_gtid_loaded) + mysql_cond_wait(&COND_slave_background, &LOCK_slave_background); + mysql_mutex_unlock(&LOCK_slave_background); + + return 0; +} + + +static void +stop_slave_background_thread() +{ + mysql_mutex_lock(&LOCK_slave_background); + slave_background_thread_stop= true; + mysql_cond_broadcast(&COND_slave_background); + while (slave_background_thread_running) + mysql_cond_wait(&COND_slave_background, &LOCK_slave_background); + mysql_mutex_unlock(&LOCK_slave_background); +======= + mysql_manager_submit(bg_gtid_pos_auto_create, table_entry->table_hton); +>>>>>>> bb-10.3-release } @@ -712,12 +852,19 @@ int init_slave() init_slave_psi_keys(); #endif - if (start_slave_background_thread()) - return 1; - if (global_rpl_thread_pool.init(opt_slave_parallel_threads)) return 1; + slave_background_thread_gtid_loaded= false; + mysql_manager_submit(bg_rpl_load_gtid_slave_state, NULL); + + // hijacking global_rpl_thread_pool cond here - it's only once on startup + mysql_mutex_lock(&global_rpl_thread_pool.LOCK_rpl_thread_pool); + while (!slave_background_thread_gtid_loaded) + mysql_cond_wait(&global_rpl_thread_pool.COND_rpl_thread_pool, + &global_rpl_thread_pool.LOCK_rpl_thread_pool); + mysql_mutex_unlock(&global_rpl_thread_pool.LOCK_rpl_thread_pool); + /* This is called when mysqld starts. Before client connections are accepted. However bootstrap may conflict with us if it does START SLAVE. @@ -1443,10 +1590,15 @@ void slave_prepare_for_shutdown() mysql_mutex_lock(&LOCK_active_mi); master_info_index->free_connections(); mysql_mutex_unlock(&LOCK_active_mi); +<<<<<<< HEAD // It's safe to destruct worker pool now when // all driver threads are gone. global_rpl_thread_pool.deactivate(); stop_slave_background_thread(); +||||||| 75538f94ca0 + stop_slave_background_thread(); +======= +>>>>>>> bb-10.3-release } /* @@ -1477,8 +1629,6 @@ void end_slave() active_mi= 0; mysql_mutex_unlock(&LOCK_active_mi); - stop_slave_background_thread(); - global_rpl_thread_pool.destroy(); free_all_rpl_filters(); DBUG_VOID_RETURN; @@ -4737,10 +4887,7 @@ pthread_handler_t handle_slave_io(void *arg) goto err; } - -#ifdef WITH_WSREP thd->variables.wsrep_on= 0; -#endif if (DBUG_EVALUATE_IF("failed_slave_start", 1, 0) || repl_semisync_slave.slave_start(mi)) { @@ -5060,8 +5207,11 @@ log space"); err: // print the current replication position if (mi->using_gtid == Master_info::USE_GTID_NO) + { sql_print_information("Slave I/O thread exiting, read up to log '%s', " "position %llu", IO_RPL_LOG_NAME, mi->master_log_pos); + sql_print_information("master was %s:%d", mi->host, mi->port); + } else { StringBuffer<100> tmp; @@ -5070,6 +5220,7 @@ err: "position %llu; GTID position %s", IO_RPL_LOG_NAME, mi->master_log_pos, tmp.c_ptr_safe()); + sql_print_information("master was %s:%d", mi->host, mi->port); } repl_semisync_slave.slave_stop(mi); thd->reset_query(); @@ -5672,6 +5823,7 @@ pthread_handler_t handle_slave_sql(void *arg) sql_print_information("Slave SQL thread exiting, replication stopped in " "log '%s' at position %llu%s", RPL_LOG_NAME, rli->group_master_log_pos, tmp.c_ptr_safe()); + sql_print_information("master was %s:%d", mi->host, mi->port); } #ifdef WITH_WSREP wsrep_after_command_before_result(thd); diff --git a/sql/spatial.cc b/sql/spatial.cc index 2b36468e158..84a05532532 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -605,6 +605,7 @@ Geometry *Geometry::create_from_json(Geometry_buffer *buffer, if (feature_type_found) goto handle_geometry_key; } + goto err_return; } else { diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index cb2757ba48f..e56361bc424 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3159,6 +3159,12 @@ end: int acl_check_setrole(THD *thd, const char *rolename, ulonglong *access) { + if (!initialized) + { + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables"); + return 1; + } + return check_user_can_set_role(thd, thd->security_ctx->priv_user, thd->security_ctx->host, thd->security_ctx->ip, rolename, access); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 9d1588a7ce1..747db4424f2 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -450,6 +450,7 @@ void thd_set_ha_data(THD *thd, const struct handlerton *hton, const void *ha_data) { plugin_ref *lock= &thd->ha_data[hton->slot].lock; + DBUG_ASSERT(thd == current_thd); if (ha_data && !*lock) *lock= ha_lock_engine(NULL, (handlerton*) hton); else if (!ha_data && *lock) @@ -457,7 +458,9 @@ void thd_set_ha_data(THD *thd, const struct handlerton *hton, plugin_unlock(NULL, *lock); *lock= NULL; } + mysql_mutex_lock(&thd->LOCK_thd_data); *thd_ha_data(thd, hton)= (void*) ha_data; + mysql_mutex_unlock(&thd->LOCK_thd_data); } @@ -1512,15 +1515,12 @@ void THD::reset_db(const LEX_CSTRING *new_db) /* Do operations that may take a long time */ -void THD::cleanup(bool have_mutex) +void THD::cleanup(void) { DBUG_ENTER("THD::cleanup"); DBUG_ASSERT(cleanup_done == 0); - if (have_mutex) - set_killed_no_mutex(KILL_CONNECTION,0,0); - else - set_killed(KILL_CONNECTION); + set_killed(KILL_CONNECTION); #ifdef WITH_WSREP if (wsrep_cs().state() != wsrep::client_state::s_none) { @@ -1611,28 +1611,6 @@ void THD::cleanup(bool have_mutex) void THD::free_connection() { DBUG_ASSERT(free_connection_done == 0); - /* Make sure threads are not available via server_threads. */ - assert_not_linked(); - - /* - Other threads may have a lock on THD::LOCK_thd_data or - THD::LOCK_thd_kill to ensure that this THD is not deleted - while they access it. The following mutex_lock ensures - that no one else is using this THD and it's now safe to - continue. - - For example consider KILL-statement execution on - sql_parse.cc kill_one_thread() that will use - THD::LOCK_thd_data to protect victim thread during - THD::awake(). - */ - mysql_mutex_lock(&LOCK_thd_data); - mysql_mutex_lock(&LOCK_thd_kill); - -#ifdef WITH_WSREP - delete wsrep_rgi; - wsrep_rgi= nullptr; -#endif /* WITH_WSREP */ my_free(const_cast<char*>(db.str)); db= null_clex_str; #ifndef EMBEDDED_LIBRARY @@ -1641,8 +1619,8 @@ void THD::free_connection() net.vio= nullptr; net_end(&net); #endif - if (!cleanup_done) - cleanup(true); // We have locked THD::LOCK_thd_kill + if (!cleanup_done) + cleanup(); ha_close_connection(this); plugin_thdvar_cleanup(this); mysql_audit_free_thd(this); @@ -1653,8 +1631,6 @@ void THD::free_connection() #if defined(ENABLED_PROFILING) profiling.restart(); // Reset profiling #endif - mysql_mutex_unlock(&LOCK_thd_kill); - mysql_mutex_unlock(&LOCK_thd_data); } /* @@ -5085,6 +5061,16 @@ thd_need_ordering_with(const MYSQL_THD thd, const MYSQL_THD other_thd) DBUG_EXECUTE_IF("disable_thd_need_ordering_with", return 1;); if (!thd || !other_thd) return 1; +#ifdef WITH_WSREP + /* wsrep applier, replayer and TOI processing threads are ordered + by replication provider, relaxed GAP locking protocol can be used + between high priority wsrep threads + */ + if (WSREP_ON && + wsrep_thd_is_BF(const_cast<THD *>(thd), false) && + wsrep_thd_is_BF(const_cast<THD *>(other_thd), true)) + return 0; +#endif /* WITH_WSREP */ rgi= thd->rgi_slave; other_rgi= other_thd->rgi_slave; if (!rgi || !other_rgi) diff --git a/sql/sql_class.h b/sql/sql_class.h index a5857a6feb0..6257588c122 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3281,7 +3281,7 @@ public: void update_all_stats(); void update_stats(void); void change_user(void); - void cleanup(bool have_mutex=false); + void cleanup(void); void cleanup_after_query(); void free_connection(); void reset_for_reuse(); @@ -6740,6 +6740,22 @@ class Sql_mode_save sql_mode_t old_mode; // SQL mode saved at construction time. }; +class Abort_on_warning_instant_set +{ + THD *m_thd; + bool m_save_abort_on_warning; +public: + Abort_on_warning_instant_set(THD *thd, bool temporary_value) + :m_thd(thd), m_save_abort_on_warning(thd->abort_on_warning) + { + thd->abort_on_warning= temporary_value; + } + ~Abort_on_warning_instant_set() + { + m_thd->abort_on_warning= m_save_abort_on_warning; + } +}; + class Switch_to_definer_security_ctx { public: diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 643b7ee898a..4d09dab392b 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -92,7 +92,6 @@ int get_or_create_user_conn(THD *thd, const char *user, uc->host= uc->user + user_len + 1; uc->len= (uint)temp_len; uc->connections= uc->questions= uc->updates= uc->conn_per_hour= 0; - uc->user_resources= *mqh; uc->reset_utime= thd->thr_create_utime; if (my_hash_insert(&hash_user_connections, (uchar*) uc)) { @@ -102,6 +101,7 @@ int get_or_create_user_conn(THD *thd, const char *user, goto end; } } + uc->user_resources= *mqh; thd->user_connect=uc; uc->connections++; end: diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 12119997430..8447d5bea7d 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -687,7 +687,6 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler, for (keypart_map= key_len=0 ; (item=it_ke++) ; key_part++) { - my_bitmap_map *old_map; /* note that 'item' can be changed by fix_fields() call */ if (item->fix_fields_if_needed_for_scalar(thd, it_ke.ref())) return 1; @@ -699,9 +698,9 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler, } if (!in_prepare) { - old_map= dbug_tmp_use_all_columns(table, table->write_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set); (void) item->save_in_field(key_part->field, 1); - dbug_tmp_restore_column_map(table->write_set, old_map); + dbug_tmp_restore_column_map(&table->write_set, old_map); } key_len+= key_part->store_length; keypart_map= (keypart_map << 1) | 1; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index cac225e01e7..6aec301bedc 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -4983,6 +4983,9 @@ bool LEX::save_prep_leaf_tables() bool st_select_lex::save_prep_leaf_tables(THD *thd) { + if (prep_leaf_list_state == SAVED) + return FALSE; + List_iterator_fast<TABLE_LIST> li(leaf_tables); TABLE_LIST *table; diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc index 2ad8d8a914a..b08e43e8af2 100644 --- a/sql/sql_manager.cc +++ b/sql/sql_manager.cc @@ -26,8 +26,8 @@ #include "sql_manager.h" #include "sql_base.h" // flush_tables -static bool volatile manager_thread_in_use; -static bool abort_manager; +static bool volatile manager_thread_in_use = 0; +static bool abort_manager = false; pthread_t manager_thread; mysql_mutex_t LOCK_manager; @@ -35,31 +35,31 @@ mysql_cond_t COND_manager; struct handler_cb { struct handler_cb *next; - void (*action)(void); + void (*action)(void *); + void *data; }; -static struct handler_cb * volatile cb_list; +static struct handler_cb *cb_list; // protected by LOCK_manager -bool mysql_manager_submit(void (*action)()) +bool mysql_manager_submit(void (*action)(void *), void *data) { bool result= FALSE; DBUG_ASSERT(manager_thread_in_use); - struct handler_cb * volatile *cb; + struct handler_cb **cb; mysql_mutex_lock(&LOCK_manager); cb= &cb_list; - while (*cb && (*cb)->action != action) + while (*cb) cb= &(*cb)->next; + *cb= (struct handler_cb *)my_malloc(sizeof(struct handler_cb), MYF(MY_WME)); if (!*cb) + result= TRUE; + else { - *cb= (struct handler_cb *)my_malloc(sizeof(struct handler_cb), MYF(MY_WME)); - if (!*cb) - result= TRUE; - else - { - (*cb)->next= NULL; - (*cb)->action= action; - } + (*cb)->next= NULL; + (*cb)->action= action; + (*cb)->data= data; } + mysql_cond_signal(&COND_manager); mysql_mutex_unlock(&LOCK_manager); return result; } @@ -69,18 +69,14 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) int error = 0; struct timespec abstime; bool reset_flush_time = TRUE; - struct handler_cb *cb= NULL; my_thread_init(); DBUG_ENTER("handle_manager"); pthread_detach_this_thread(); manager_thread = pthread_self(); - mysql_cond_init(key_COND_manager, &COND_manager,NULL); - mysql_mutex_init(key_LOCK_manager, &LOCK_manager, NULL); - manager_thread_in_use = 1; - for (;;) + mysql_mutex_lock(&LOCK_manager); + while (!abort_manager) { - mysql_mutex_lock(&LOCK_manager); /* XXX: This will need to be made more general to handle different * polling needs. */ if (flush_time) @@ -90,40 +86,37 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) set_timespec(abstime, flush_time); reset_flush_time = FALSE; } - while ((!error || error == EINTR) && !abort_manager) + while ((!error || error == EINTR) && !abort_manager && !cb_list) error= mysql_cond_timedwait(&COND_manager, &LOCK_manager, &abstime); + + if (error == ETIMEDOUT || error == ETIME) + { + tc_purge(); + error = 0; + reset_flush_time = TRUE; + } } else { - while ((!error || error == EINTR) && !abort_manager) + while ((!error || error == EINTR) && !abort_manager && !cb_list) error= mysql_cond_wait(&COND_manager, &LOCK_manager); } - if (cb == NULL) - { - cb= cb_list; - cb_list= NULL; - } - mysql_mutex_unlock(&LOCK_manager); - if (abort_manager) - break; - - if (error == ETIMEDOUT || error == ETIME) - { - tc_purge(); - error = 0; - reset_flush_time = TRUE; - } + struct handler_cb *cb= cb_list; + cb_list= NULL; + mysql_mutex_unlock(&LOCK_manager); while (cb) { struct handler_cb *next= cb->next; - cb->action(); + cb->action(cb->data); my_free(cb); cb= next; } + mysql_mutex_lock(&LOCK_manager); } manager_thread_in_use = 0; + mysql_mutex_unlock(&LOCK_manager); mysql_mutex_destroy(&LOCK_manager); mysql_cond_destroy(&COND_manager); DBUG_LEAVE; // Can't use DBUG_RETURN after my_thread_end @@ -137,15 +130,15 @@ void start_handle_manager() { DBUG_ENTER("start_handle_manager"); abort_manager = false; - if (flush_time && flush_time != ~(ulong) 0L) { pthread_t hThread; - int error; - if ((error= mysql_thread_create(key_thread_handle_manager, - &hThread, &connection_attrib, - handle_manager, 0))) - sql_print_warning("Can't create handle_manager thread (errno= %d)", - error); + int err; + manager_thread_in_use = 1; + mysql_cond_init(key_COND_manager, &COND_manager,NULL); + mysql_mutex_init(key_LOCK_manager, &LOCK_manager, NULL); + if ((err= mysql_thread_create(key_thread_handle_manager, &hThread, + &connection_attrib, handle_manager, 0))) + sql_print_warning("Can't create handle_manager thread (errno: %M)", err); } DBUG_VOID_RETURN; } @@ -155,10 +148,10 @@ void start_handle_manager() void stop_handle_manager() { DBUG_ENTER("stop_handle_manager"); - abort_manager = true; if (manager_thread_in_use) { mysql_mutex_lock(&LOCK_manager); + abort_manager = true; DBUG_PRINT("quit", ("initiate shutdown of handle manager thread: %lu", (ulong)manager_thread)); mysql_cond_signal(&COND_manager); diff --git a/sql/sql_manager.h b/sql/sql_manager.h index 9c6c84450ed..f97d4a2cfc5 100644 --- a/sql/sql_manager.h +++ b/sql/sql_manager.h @@ -18,6 +18,6 @@ void start_handle_manager(); void stop_handle_manager(); -bool mysql_manager_submit(void (*action)()); +bool mysql_manager_submit(void (*action)(void *), void *data); #endif /* SQL_MANAGER_INCLUDED */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 209caa9460e..de96f0c8924 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2220,6 +2220,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; general_log_print(thd, command, NullS); status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]); + *current_global_status_var= global_status_var; calc_sum_of_all_status(current_global_status_var); if (!(uptime= (ulong) (thd->start_time - server_start_time))) queries_per_second1000= 0; diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index c9c75d07a6e..6bd60fdd6c5 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -22,11 +22,13 @@ that is defined in plugin.h */ #define SHOW_always_last SHOW_KEY_CACHE_LONG, \ - SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, \ SHOW_HAVE, SHOW_MY_BOOL, SHOW_HA_ROWS, SHOW_SYS, \ - SHOW_LONG_NOFLUSH, SHOW_LONGLONG_STATUS, SHOW_UINT32_STATUS, \ - SHOW_LEX_STRING, SHOW_ATOMIC_COUNTER_UINT32_T -#include "mariadb.h" + SHOW_LONG_NOFLUSH, SHOW_LEX_STRING, \ + SHOW_ATOMIC_COUNTER_UINT32_T, \ + /* SHOW_*_STATUS must be at the end, SHOW_LONG_STATUS being first */ \ + SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, SHOW_LONGLONG_STATUS, \ + SHOW_UINT32_STATUS +#include <my_global.h> #undef SHOW_always_last #include "m_string.h" /* LEX_STRING */ diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 0312bc9a758..ea6bfe03be5 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -122,6 +122,7 @@ When one supplies long data for a placeholder: static const uint PARAMETER_FLAG_UNSIGNED= 128U << 8; #endif #include "lock.h" // MYSQL_OPEN_FORCE_SHARED_MDL +#include "log_event.h" // class Log_event #include "sql_handler.h" #include "transaction.h" // trans_rollback_implicit #ifdef WITH_WSREP @@ -2487,6 +2488,16 @@ static bool check_prepared_statement(Prepared_statement *stmt) DBUG_RETURN(FALSE); } break; + case SQLCOM_SHOW_BINLOG_EVENTS: + case SQLCOM_SHOW_RELAYLOG_EVENTS: + { + List<Item> field_list; + Log_event::init_show_field_list(thd, &field_list); + + if ((res= send_stmt_metadata(thd, stmt, &field_list)) == 2) + DBUG_RETURN(FALSE); + } + break; #endif /* EMBEDDED_LIBRARY */ case SQLCOM_SHOW_CREATE_PROC: if ((res= mysql_test_show_create_routine(stmt, &sp_handler_procedure)) == 2) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 5203e0f52a5..622eff2faae 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -4685,5 +4685,22 @@ rpl_gtid_pos_update(THD *thd, char *str, size_t len) return false; } +int compare_log_name(const char *log_1, const char *log_2) { + int res= 1; + const char *ext1_str= strrchr(log_1, '.'); + const char *ext2_str= strrchr(log_2, '.'); + char file_name_1[255], file_name_2[255]; + strmake(file_name_1, log_1, (ext1_str - log_1)); + strmake(file_name_2, log_2, (ext2_str - log_2)); + char *endptr = NULL; + res= strcmp(file_name_1, file_name_2); + if (!res) + { + ulong ext1= strtoul(++ext1_str, &endptr, 10); + ulong ext2= strtoul(++ext2_str, &endptr, 10); + res= (ext1 > ext2 ? 1 : ((ext1 == ext2) ? 0 : -1)); + } + return res; +} #endif /* HAVE_REPLICATION */ diff --git a/sql/sql_repl.h b/sql/sql_repl.h index 18aa7ea3fce..95916e31abf 100644 --- a/sql/sql_repl.h +++ b/sql/sql_repl.h @@ -45,6 +45,7 @@ bool show_binlogs(THD* thd); extern int init_master_info(Master_info* mi); void kill_zombie_dump_threads(uint32 slave_server_id); int check_binlog_magic(IO_CACHE* log, const char** errmsg); +int compare_log_name(const char *log_1, const char *log_2); struct LOAD_FILE_IO_CACHE : public IO_CACHE { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4bbe5ce9141..e89bb1fd442 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2097,7 +2097,7 @@ JOIN::optimize_inner() join->optimization_state == JOIN::OPTIMIZATION_PHASE_1_DONE && join->with_two_phase_optimization) continue; - /* + /* Do not push conditions from where into materialized inner tables of outer joins: this is not valid. */ @@ -2298,7 +2298,7 @@ setup_subq_exit: if (with_two_phase_optimization) optimization_state= JOIN::OPTIMIZATION_PHASE_1_DONE; else - { + { if (optimize_stage2()) DBUG_RETURN(1); } @@ -2318,11 +2318,11 @@ int JOIN::optimize_stage2() if (unlikely(thd->check_killed())) DBUG_RETURN(1); - + /* Generate an execution plan from the found optimal join order. */ if (get_best_combination()) DBUG_RETURN(1); - + if (make_range_rowid_filters()) DBUG_RETURN(1); @@ -3965,7 +3965,7 @@ bool JOIN::setup_subquery_caches() if (tmp_having) { DBUG_ASSERT(having == NULL); - if (!(tmp_having= + if (!(tmp_having= tmp_having->transform(thd, &Item::expr_cache_insert_transformer, NULL))) @@ -6893,7 +6893,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, Special treatment for ft-keys. */ -bool sort_and_filter_keyuse(THD *thd, DYNAMIC_ARRAY *keyuse, +bool sort_and_filter_keyuse(THD *thd, DYNAMIC_ARRAY *keyuse, bool skip_unprefixed_keyparts) { KEYUSE key_end, *prev, *save_pos, *use; @@ -8064,7 +8064,7 @@ best_access_path(JOIN *join, pos->use_join_buffer= best_uses_jbuf; pos->spl_plan= spl_plan; pos->range_rowid_filter_info= best_filter; - + loose_scan_opt.save_to_position(s, loose_scan_pos); if (!best_key && @@ -10208,7 +10208,7 @@ bool JOIN::check_two_phase_optimization(THD *thd) return true; return false; } - + bool JOIN::inject_cond_into_where(Item *injected_cond) { @@ -10239,7 +10239,7 @@ bool JOIN::inject_cond_into_where(Item *injected_cond) and_args->push_back(elem, thd->mem_root); } } - + return false; } @@ -24036,7 +24036,7 @@ bool cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref) { Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE); - my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set); bool result= 0; for (store_key **copy=ref->key_copy ; *copy ; copy++) @@ -24047,7 +24047,7 @@ cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref) break; } } - dbug_tmp_restore_column_map(table->write_set, old_map); + dbug_tmp_restore_column_map(&table->write_set, old_map); return result; } @@ -25718,7 +25718,7 @@ bool JOIN::rollup_init() { if (!(rollup.null_items[i]= new (thd->mem_root) Item_null_result(thd))) return true; - + List<Item> *rollup_fields= &rollup.fields[i]; rollup_fields->empty(); rollup.ref_pointer_arrays[i]= Ref_ptr_array(ref_array, all_fields.elements); @@ -26228,7 +26228,7 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, { JOIN_TAB *ctab= bush_children->start; /* table */ - size_t len= my_snprintf(table_name_buffer, + size_t len= my_snprintf(table_name_buffer, sizeof(table_name_buffer)-1, "<subquery%d>", ctab->emb_sj_nest->sj_subq_pred->get_identifier()); @@ -27403,7 +27403,7 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str, void st_select_lex::print(THD *thd, String *str, enum_query_type query_type) { DBUG_ASSERT(thd); - + if (tvc) { tvc->print(thd, str, query_type); diff --git a/sql/sql_select.h b/sql/sql_select.h index e14907d73bc..1d928334bd8 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1948,8 +1948,8 @@ class store_key_field: public store_key enum store_key_result copy_inner() { TABLE *table= copy_field.to_field->table; - my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, - table->write_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, + &table->write_set); /* It looks like the next statement is needed only for a simplified @@ -1960,7 +1960,7 @@ class store_key_field: public store_key bzero(copy_field.to_ptr,copy_field.to_length); copy_field.do_copy(©_field); - dbug_tmp_restore_column_map(table->write_set, old_map); + dbug_tmp_restore_column_map(&table->write_set, old_map); null_key= to_field->is_null(); return err != 0 ? STORE_KEY_FATAL : STORE_KEY_OK; } @@ -1995,8 +1995,8 @@ public: enum store_key_result copy_inner() { TABLE *table= to_field->table; - my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, - table->write_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, + &table->write_set); int res= FALSE; /* @@ -2017,7 +2017,7 @@ public: */ if (!res && table->in_use->is_error()) res= 1; /* STORE_KEY_FATAL */ - dbug_tmp_restore_column_map(table->write_set, old_map); + dbug_tmp_restore_column_map(&table->write_set, old_map); null_key= to_field->is_null() || item->null_value; return ((err != 0 || res < 0 || res > 2) ? STORE_KEY_FATAL : (store_key_result) res); @@ -2053,8 +2053,8 @@ protected: { inited=1; TABLE *table= to_field->table; - my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, - table->write_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, + &table->write_set); if ((res= item->save_in_field(to_field, 1))) { if (!err) @@ -2066,7 +2066,7 @@ protected: */ if (!err && to_field->table->in_use->is_error()) err= 1; /* STORE_KEY_FATAL */ - dbug_tmp_restore_column_map(table->write_set, old_map); + dbug_tmp_restore_column_map(&table->write_set, old_map); } null_key= to_field->is_null() || item->null_value; return (err > 2 ? STORE_KEY_FATAL : (store_key_result) err); diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc index a2bcfd5a4ff..b88933eac0c 100644 --- a/sql/sql_sequence.cc +++ b/sql/sql_sequence.cc @@ -136,7 +136,7 @@ bool sequence_definition::check_and_adjust(bool set_reserved_until) void sequence_definition::read_fields(TABLE *table) { - my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->read_set); reserved_until= table->field[0]->val_int(); min_value= table->field[1]->val_int(); max_value= table->field[2]->val_int(); @@ -145,7 +145,7 @@ void sequence_definition::read_fields(TABLE *table) cache= table->field[5]->val_int(); cycle= table->field[6]->val_int(); round= table->field[7]->val_int(); - dbug_tmp_restore_column_map(table->read_set, old_map); + dbug_tmp_restore_column_map(&table->read_set, old_map); used_fields= ~(uint) 0; print_dbug(); } @@ -157,7 +157,7 @@ void sequence_definition::read_fields(TABLE *table) void sequence_definition::store_fields(TABLE *table) { - my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set); /* zero possible delete markers & null bits */ memcpy(table->record[0], table->s->default_values, table->s->null_bytes); @@ -170,7 +170,7 @@ void sequence_definition::store_fields(TABLE *table) table->field[6]->store((longlong) cycle != 0, 0); table->field[7]->store((longlong) round, 1); - dbug_tmp_restore_column_map(table->write_set, old_map); + dbug_tmp_restore_column_map(&table->write_set, old_map); print_dbug(); } @@ -527,12 +527,11 @@ int SEQUENCE::read_initial_values(TABLE *table) int SEQUENCE::read_stored_values(TABLE *table) { int error; - my_bitmap_map *save_read_set; DBUG_ENTER("SEQUENCE::read_stored_values"); - save_read_set= tmp_use_all_columns(table, table->read_set); + MY_BITMAP *save_read_set= tmp_use_all_columns(table, &table->read_set); error= table->file->ha_read_first_row(table->record[0], MAX_KEY); - tmp_restore_column_map(table->read_set, save_read_set); + tmp_restore_column_map(&table->read_set, save_read_set); if (unlikely(error)) { diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 12da17e7f10..ad2a489c39d 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2147,7 +2147,6 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, !foreign_db_mode; bool check_options= !(sql_mode & MODE_IGNORE_BAD_TABLE_OPTIONS) && !create_info_arg; - my_bitmap_map *old_map; handlerton *hton; int error= 0; DBUG_ENTER("show_create_table"); @@ -2214,7 +2213,7 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, We have to restore the read_set if we are called from insert in case of row based replication. */ - old_map= tmp_use_all_columns(table, table->read_set); + MY_BITMAP *old_map= tmp_use_all_columns(table, &table->read_set); bool not_the_first_field= false; for (ptr=table->field ; (field= *ptr); ptr++) @@ -2259,8 +2258,13 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, /* For string types dump collation name only if collation is not primary for the given charset + + For generated fields don't print the COLLATE clause if + the collation matches the expression's collation. */ - if (!(field->charset()->state & MY_CS_PRIMARY) && !field->vcol_info) + if (!(field->charset()->state & MY_CS_PRIMARY) && + (!field->vcol_info || + field->charset() != field->vcol_info->expr->collation.collation)) { packet->append(STRING_WITH_LEN(" COLLATE ")); packet->append(field->charset()->name); @@ -2516,7 +2520,7 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, } } #endif - tmp_restore_column_map(table->read_set, old_map); + tmp_restore_column_map(&table->read_set, old_map); DBUG_RETURN(error); } @@ -3832,6 +3836,16 @@ static bool show_status_array(THD *thd, const char *wild, if (show_type == SHOW_SYS) mysql_mutex_lock(&LOCK_global_system_variables); + else if (show_type >= SHOW_LONG_STATUS && scope == OPT_GLOBAL && + !status_var->local_memory_used) + { + mysql_mutex_lock(&LOCK_status); + *status_var= global_status_var; + mysql_mutex_unlock(&LOCK_status); + calc_sum_of_all_status(status_var); + DBUG_ASSERT(status_var->local_memory_used); + } + pos= get_one_variable(thd, var, scope, show_type, status_var, &charset, buff, &length); @@ -3889,7 +3903,6 @@ uint calc_sum_of_all_status(STATUS_VAR *to) calc_sum_callback_arg arg(to); DBUG_ENTER("calc_sum_of_all_status"); - *to= global_status_var; to->local_memory_used= 0; /* Add to this status from existing threads */ server_threads.iterate(calc_sum_callback, &arg); @@ -5298,6 +5311,12 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) continue; } + if (thd->killed == ABORT_QUERY) + { + error= 0; + goto err; + } + DEBUG_SYNC(thd, "before_open_in_get_all_tables"); if (fill_schema_table_by_open(thd, &tmp_mem_root, FALSE, table, schema_table, @@ -5866,7 +5885,7 @@ static bool print_anchor_data_type(const Spvar_definition *def, Let's print it according to the current sql_mode. It will make output in line with the value in mysql.proc.param_list, so both I_S.XXX.DTD_IDENTIFIER and mysql.proc.param_list use the same notation: - default or Oracle, according to the sql_mode at the SP creation time. + default or Oracle, according to the sql_mode at the SP creation time. The caller must make sure to set thd->variables.sql_mode to the routine sql_mode. */ static bool print_anchor_dtd_identifier(THD *thd, const Spvar_definition *def, @@ -7970,10 +7989,7 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond) if (partial_cond) partial_cond->val_int(); - if (scope == OPT_GLOBAL) - { - calc_sum_of_all_status(&tmp); - } + tmp.local_memory_used= 0; // meaning tmp was not populated yet mysql_rwlock_rdlock(&LOCK_all_status_vars); res= show_status_array(thd, wild, diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 717deeabe18..e7d380ebb2d 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -1024,9 +1024,8 @@ public: { char buff[MAX_FIELD_WIDTH]; String val(buff, sizeof(buff), &my_charset_bin); - my_bitmap_map *old_map; - old_map= dbug_tmp_use_all_columns(stat_table, stat_table->read_set); + MY_BITMAP *old_map= dbug_tmp_use_all_columns(stat_table, &stat_table->read_set); for (uint i= COLUMN_STAT_MIN_VALUE; i <= COLUMN_STAT_HISTOGRAM; i++) { Field *stat_field= stat_table->field[i]; @@ -1084,7 +1083,7 @@ public: } } } - dbug_tmp_restore_column_map(stat_table->read_set, old_map); + dbug_tmp_restore_column_map(&stat_table->read_set, old_map); } @@ -2121,6 +2120,10 @@ int alloc_statistics_for_table(THD* thd, TABLE *table) ulonglong *idx_avg_frequency= (ulonglong*) alloc_root(&table->mem_root, sizeof(ulonglong) * key_parts); + if (table->file->ha_rnd_init(TRUE)) + DBUG_RETURN(1); + table->file->ha_rnd_end(); + uint columns= 0; for (field_ptr= table->field; *field_ptr; field_ptr++) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4ddfcabf6c8..18b34e4a212 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4072,8 +4072,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, key_part_length= MY_MIN(max_key_length, file->max_key_part_length()); /* not a critical problem */ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, - ER_TOO_LONG_KEY, - ER_THD(thd, ER_TOO_LONG_KEY), + ER_TOO_LONG_KEY, ER_THD(thd, ER_TOO_LONG_KEY), key_part_length); /* Align key length to multibyte char boundary */ key_part_length-= key_part_length % sql_field->charset->mbmaxlen; @@ -4117,7 +4116,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, { key_part_length= file->max_key_part_length(); /* not a critical problem */ - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_TOO_LONG_KEY, ER_THD(thd, ER_TOO_LONG_KEY), key_part_length); /* Align key length to multibyte char boundary */ @@ -4398,7 +4397,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, ER_ILLEGAL_HA_CREATE_OPTION, ER_THD(thd, ER_ILLEGAL_HA_CREATE_OPTION), file->engine_name()->str, - "TRANSACTIONAL=1"); + create_info->transactional == HA_CHOICE_YES + ? "TRANSACTIONAL=1" : "TRANSACTIONAL=0"); if (parse_option_list(thd, file->partition_ht(), &create_info->option_struct, &create_info->option_list, @@ -5299,6 +5299,9 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, if (!opt_explicit_defaults_for_timestamp) promote_first_timestamp_column(&alter_info->create_list); + /* We can abort create table for any table type */ + thd->abort_on_warning= thd->is_strict_mode(); + if (mysql_create_table_no_lock(thd, &create_table->db, &create_table->table_name, create_info, alter_info, @@ -5336,6 +5339,8 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, } err: + thd->abort_on_warning= 0; + /* In RBR or readonly server we don't need to log CREATE TEMPORARY TABLE */ if (!result && create_info->tmp_table() && (thd->is_current_stmt_binlog_format_row() || (opt_readonly && !thd->slave_thread))) diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 08dc137bebe..54eed6e4c90 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -565,6 +565,7 @@ void mysql_print_status() STATUS_VAR tmp; uint count; + tmp= global_status_var; count= calc_sum_of_all_status(&tmp); printf("\nStatus information:\n\n"); (void) my_getwd(current_dir, sizeof(current_dir),MYF(0)); diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc index 916047c4b0f..33ee2dd381c 100644 --- a/sql/sql_tvc.cc +++ b/sql/sql_tvc.cc @@ -47,7 +47,7 @@ bool fix_fields_for_tvc(THD *thd, List_iterator_fast<List_item> &li) while ((lst= li++)) { - List_iterator_fast<Item> it(*lst); + List_iterator<Item> it(*lst); Item *item; while ((item= it++)) @@ -59,7 +59,7 @@ bool fix_fields_for_tvc(THD *thd, List_iterator_fast<List_item> &li) while replacing their values to NAME_CONST()s. So fix only those that have not been. */ - if (item->fix_fields_if_needed(thd, 0) || + if (item->fix_fields_if_needed_for_scalar(thd, it.ref()) || item->check_is_evaluable_expression_or_error()) DBUG_RETURN(true); } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index d64a96f5070..2a82b1b2332 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1718,6 +1718,9 @@ bool Multiupdate_prelocking_strategy::handle_end(THD *thd) if (select_lex->handle_derived(thd->lex, DT_MERGE)) DBUG_RETURN(1); + if (thd->lex->save_prep_leaf_tables()) + DBUG_RETURN(1); + List<Item> *fields= &lex->first_select_lex()->item_list; if (setup_fields_with_no_wrap(thd, Ref_ptr_array(), *fields, MARK_COLUMNS_WRITE, 0, 0)) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2548dc28731..9b2355e53c5 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -829,7 +829,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); /* We should not introduce any further shift/reduce conflicts. */ -%expect 47 +%expect 68 /* Comments for TOKENS. @@ -1808,7 +1808,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type <type_handler> int_type real_type -%type <Lex_field_type> type_with_opt_collate field_type +%type <Lex_field_type> field_type field_type_all qualified_field_type field_type_numeric field_type_string @@ -3392,7 +3392,7 @@ sp_param_name: ; sp_param_name_and_type: - sp_param_name type_with_opt_collate + sp_param_name field_type { if (unlikely(Lex->sp_param_fill_definition($$= $1))) MYSQL_YYABORT; @@ -3522,7 +3522,7 @@ row_field_name: ; row_field_definition: - row_field_name type_with_opt_collate + row_field_name field_type ; row_field_definition_list: @@ -3551,7 +3551,7 @@ sp_decl_idents_init_vars: sp_decl_variable_list: sp_decl_idents_init_vars - type_with_opt_collate + field_type sp_opt_default { if (unlikely(Lex->sp_variable_declarations_finalize(thd, $1, @@ -6888,19 +6888,26 @@ column_default_expr: } ; +field_type: field_type_all + { + Lex->map_data_type(Lex_ident_sys(), &($$= $1)); + Lex->last_field->set_attributes($$, Lex->charset); + } + ; + qualified_field_type: - field_type + field_type_all { Lex->map_data_type(Lex_ident_sys(), &($$= $1)); } - | sp_decl_ident '.' field_type + | sp_decl_ident '.' field_type_all { if (Lex->map_data_type($1, &($$= $3))) MYSQL_YYABORT; } ; -field_type: +field_type_all: field_type_numeric | field_type_temporal | field_type_string @@ -7363,20 +7370,6 @@ with_or_without_system: ; -type_with_opt_collate: - field_type opt_collate - { - Lex->map_data_type(Lex_ident_sys(), &($$= $1)); - - if ($2) - { - if (unlikely(!(Lex->charset= merge_charset_and_collation(Lex->charset, $2)))) - MYSQL_YYABORT; - } - Lex->last_field->set_attributes($$, Lex->charset); - } - ; - charset: CHAR_SYM SET {} | CHARSET {} @@ -7450,6 +7443,12 @@ charset_or_alias: } ; +collate: COLLATE_SYM collation_name_or_default + { + Lex->charset= $2; + } + ; + opt_binary: /* empty */ { bincmp_collation(NULL, false); } | binary {} @@ -7460,6 +7459,13 @@ binary: | charset_or_alias opt_bin_mod { bincmp_collation($1, $2); } | BINARY { bincmp_collation(NULL, true); } | BINARY charset_or_alias { bincmp_collation($2, true); } + | charset_or_alias collate + { + if (!my_charset_same(Lex->charset, $1)) + my_yyabort_error((ER_COLLATION_CHARSET_MISMATCH, MYF(0), + Lex->charset->name, $1->csname)); + } + | collate { } ; opt_bin_mod: @@ -14989,7 +14995,7 @@ kill: lex->sql_command= SQLCOM_KILL; lex->kill_type= KILL_TYPE_ID; } - kill_type kill_option kill_expr + kill_type kill_option { Lex->kill_signal= (killed_state) ($3 | $4); } @@ -15002,16 +15008,21 @@ kill_type: ; kill_option: - /* empty */ { $$= (int) KILL_CONNECTION; } - | CONNECTION_SYM { $$= (int) KILL_CONNECTION; } - | QUERY_SYM { $$= (int) KILL_QUERY; } - | QUERY_SYM ID_SYM + opt_connection kill_expr { $$= (int) KILL_CONNECTION; } + | QUERY_SYM kill_expr { $$= (int) KILL_QUERY; } + | QUERY_SYM ID_SYM expr { $$= (int) KILL_QUERY; Lex->kill_type= KILL_TYPE_QUERY; + Lex->value_list.push_front($3, thd->mem_root); } ; +opt_connection: + /* empty */ { } + | CONNECTION_SYM { } + ; + kill_expr: expr { @@ -15024,7 +15035,6 @@ kill_expr: } ; - shutdown: SHUTDOWN { Lex->sql_command= SQLCOM_SHUTDOWN; } shutdown_option {} @@ -18024,7 +18034,7 @@ sf_return_type: &empty_clex_str, thd->variables.collation_database); } - type_with_opt_collate + field_type { if (unlikely(Lex->sphead->fill_field_definition(thd, Lex->last_field))) diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 30727a8ffc4..cb58c4aff43 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -305,7 +305,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); /* We should not introduce any further shift/reduce conflicts. */ -%expect 50 +%expect 70 /* Comments for TOKENS. @@ -1288,9 +1288,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type <type_handler> int_type real_type -%type <Lex_field_type> type_with_opt_collate field_type +%type <Lex_field_type> field_type field_type_all qualified_field_type - sp_param_type_with_opt_collate + sp_param_type sp_param_field_type sp_param_field_type_string field_type_numeric @@ -3194,7 +3194,7 @@ sp_param_name: ; sp_param_name_and_type: - sp_param_name sp_param_type_with_opt_collate + sp_param_name sp_param_type { if (unlikely(Lex->sp_param_fill_definition($$= $1))) MYSQL_YYABORT; @@ -3238,7 +3238,7 @@ sp_pdparams: ; sp_pdparam: - sp_param_name sp_opt_inout sp_param_type_with_opt_collate + sp_param_name sp_opt_inout sp_param_type { $1->mode= $2; if (unlikely(Lex->sp_param_fill_definition($1))) @@ -3407,7 +3407,7 @@ row_field_name: ; row_field_definition: - row_field_name type_with_opt_collate + row_field_name field_type ; row_field_definition_list: @@ -3436,7 +3436,7 @@ sp_decl_idents_init_vars: sp_decl_vars: sp_decl_idents_init_vars - type_with_opt_collate + field_type sp_opt_default { if (unlikely(Lex->sp_variable_declarations_finalize(thd, $1, @@ -6891,19 +6891,26 @@ column_default_expr: } ; +field_type: field_type_all + { + Lex->map_data_type(Lex_ident_sys(), &($$= $1)); + Lex->last_field->set_attributes($$, Lex->charset); + } + ; + qualified_field_type: - field_type + field_type_all { Lex->map_data_type(Lex_ident_sys(), &($$= $1)); } - | sp_decl_ident '.' field_type + | sp_decl_ident '.' field_type_all { if (Lex->map_data_type($1, &($$= $3))) MYSQL_YYABORT; } ; -field_type: +field_type_all: field_type_numeric | field_type_temporal | field_type_string @@ -7445,30 +7452,10 @@ with_or_without_system: ; -type_with_opt_collate: - field_type opt_collate - { - Lex->map_data_type(Lex_ident_sys(), &($$= $1)); - - if ($2) - { - if (unlikely(!(Lex->charset= merge_charset_and_collation(Lex->charset, $2)))) - MYSQL_YYABORT; - } - Lex->last_field->set_attributes($$, Lex->charset); - } - ; - -sp_param_type_with_opt_collate: - sp_param_field_type opt_collate +sp_param_type: + sp_param_field_type { Lex->map_data_type(Lex_ident_sys(), &($$= $1)); - - if ($2) - { - if (unlikely(!(Lex->charset= merge_charset_and_collation(Lex->charset, $2)))) - MYSQL_YYABORT; - } Lex->last_field->set_attributes($$, Lex->charset); } ; @@ -7546,6 +7533,12 @@ charset_or_alias: } ; +collate: COLLATE_SYM collation_name_or_default + { + Lex->charset= $2; + } + ; + opt_binary: /* empty */ { bincmp_collation(NULL, false); } | binary {} @@ -7556,6 +7549,13 @@ binary: | charset_or_alias opt_bin_mod { bincmp_collation($1, $2); } | BINARY { bincmp_collation(NULL, true); } | BINARY charset_or_alias { bincmp_collation($2, true); } + | charset_or_alias collate + { + if (!my_charset_same(Lex->charset, $1)) + my_yyabort_error((ER_COLLATION_CHARSET_MISMATCH, MYF(0), + Lex->charset->name, $1->csname)); + } + | collate { } ; opt_bin_mod: @@ -15113,7 +15113,7 @@ kill: lex->sql_command= SQLCOM_KILL; lex->kill_type= KILL_TYPE_ID; } - kill_type kill_option kill_expr + kill_type kill_option { Lex->kill_signal= (killed_state) ($3 | $4); } @@ -15126,16 +15126,21 @@ kill_type: ; kill_option: - /* empty */ { $$= (int) KILL_CONNECTION; } - | CONNECTION_SYM { $$= (int) KILL_CONNECTION; } - | QUERY_SYM { $$= (int) KILL_QUERY; } - | QUERY_SYM ID_SYM + opt_connection kill_expr { $$= (int) KILL_CONNECTION; } + | QUERY_SYM kill_expr { $$= (int) KILL_QUERY; } + | QUERY_SYM ID_SYM expr { $$= (int) KILL_QUERY; Lex->kill_type= KILL_TYPE_QUERY; + Lex->value_list.push_front($3, thd->mem_root); } ; +opt_connection: + /* empty */ { } + | CONNECTION_SYM { } + ; + kill_expr: expr { @@ -15148,7 +15153,6 @@ kill_expr: } ; - shutdown: SHUTDOWN { Lex->sql_command= SQLCOM_SHUTDOWN; } shutdown_option {} @@ -18236,7 +18240,7 @@ sf_return_type: &empty_clex_str, thd->variables.collation_database); } - sp_param_type_with_opt_collate + sp_param_type { if (unlikely(Lex->sphead->fill_field_definition(thd, Lex->last_field))) diff --git a/sql/table.h b/sql/table.h index 4c9efdf3529..bb0e087bacb 100644 --- a/sql/table.h +++ b/sql/table.h @@ -3087,25 +3087,25 @@ typedef struct st_open_table_list{ } OPEN_TABLE_LIST; -static inline my_bitmap_map *tmp_use_all_columns(TABLE *table, - MY_BITMAP *bitmap) +static inline MY_BITMAP *tmp_use_all_columns(TABLE *table, + MY_BITMAP **bitmap) { - my_bitmap_map *old= bitmap->bitmap; - bitmap->bitmap= table->s->all_set.bitmap; + MY_BITMAP *old= *bitmap; + *bitmap= &table->s->all_set; return old; } -static inline void tmp_restore_column_map(MY_BITMAP *bitmap, - my_bitmap_map *old) +static inline void tmp_restore_column_map(MY_BITMAP **bitmap, + MY_BITMAP *old) { - bitmap->bitmap= old; + *bitmap= old; } /* The following is only needed for debugging */ -static inline my_bitmap_map *dbug_tmp_use_all_columns(TABLE *table, - MY_BITMAP *bitmap) +static inline MY_BITMAP *dbug_tmp_use_all_columns(TABLE *table, + MY_BITMAP **bitmap) { #ifdef DBUG_ASSERT_EXISTS return tmp_use_all_columns(table, bitmap); @@ -3114,8 +3114,8 @@ static inline my_bitmap_map *dbug_tmp_use_all_columns(TABLE *table, #endif } -static inline void dbug_tmp_restore_column_map(MY_BITMAP *bitmap, - my_bitmap_map *old) +static inline void dbug_tmp_restore_column_map(MY_BITMAP **bitmap, + MY_BITMAP *old) { #ifdef DBUG_ASSERT_EXISTS tmp_restore_column_map(bitmap, old); @@ -3128,22 +3128,22 @@ static inline void dbug_tmp_restore_column_map(MY_BITMAP *bitmap, Provide for the possiblity of the read set being the same as the write set */ static inline void dbug_tmp_use_all_columns(TABLE *table, - my_bitmap_map **save, - MY_BITMAP *read_set, - MY_BITMAP *write_set) + MY_BITMAP **save, + MY_BITMAP **read_set, + MY_BITMAP **write_set) { #ifdef DBUG_ASSERT_EXISTS - save[0]= read_set->bitmap; - save[1]= write_set->bitmap; + save[0]= *read_set; + save[1]= *write_set; (void) tmp_use_all_columns(table, read_set); (void) tmp_use_all_columns(table, write_set); #endif } -static inline void dbug_tmp_restore_column_maps(MY_BITMAP *read_set, - MY_BITMAP *write_set, - my_bitmap_map **old) +static inline void dbug_tmp_restore_column_maps(MY_BITMAP **read_set, + MY_BITMAP **write_set, + MY_BITMAP **old) { #ifdef DBUG_ASSERT_EXISTS tmp_restore_column_map(read_set, old[0]); diff --git a/sql/unireg.cc b/sql/unireg.cc index 17222efe791..b09178de7ed 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -1028,6 +1028,8 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options, TABLE table; TABLE_SHARE share; Create_field *field; + Check_level_instant_set old_count_cuted_fields(thd, CHECK_FIELD_WARN); + Abort_on_warning_instant_set old_abort_on_warning(thd, 0); DBUG_ENTER("make_empty_rec"); /* We need a table to generate columns for default values */ @@ -1046,7 +1048,6 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options, null_pos= buff; List_iterator<Create_field> it(create_fields); - Check_level_instant_set check_level_save(thd, CHECK_FIELD_WARN); while ((field=it++)) { Record_addr addr(buff + field->offset + data_offset, diff --git a/sql/upgrade_conf_file.cc b/sql/upgrade_conf_file.cc index 4e167f0263f..b40cce0bbd7 100644 --- a/sql/upgrade_conf_file.cc +++ b/sql/upgrade_conf_file.cc @@ -75,6 +75,7 @@ static const char *removed_variables[] = "innodb_ibuf_accel_rate", "innodb_ibuf_active_contract", "innodb_ibuf_max_size", +"innodb_idle_flush_pct", "innodb_import_table_from_xtrabackup", "innodb_instrument_semaphores", "innodb_kill_idle_transaction", diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index b7a7dadf0dc..23de4d7f7c1 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -265,6 +265,12 @@ static bool sst_auth_real_set (const char* value) if (wsrep_sst_auth) { my_free((void*) wsrep_sst_auth); } wsrep_sst_auth= my_strdup(WSREP_SST_AUTH_MASK, MYF(0)); } + else + { + if (wsrep_sst_auth) { my_free((void*) wsrep_sst_auth); } + wsrep_sst_auth= NULL; + } + return 0; } return 1; diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index 0f72c132d84..323439025c5 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -68,7 +68,546 @@ static void wsrep_replication_process(THD *thd, thd->wsrep_rgi->cleanup_after_session(); delete thd->wsrep_rgi; +<<<<<<< HEAD thd->wsrep_rgi= NULL; +||||||| 75538f94ca0 + thd->wsrep_rgi = NULL; + thd->set_row_count_func(shadow->row_count_func); +} + +void wsrep_replay_sp_transaction(THD* thd) +{ + DBUG_ENTER("wsrep_replay_sp_transaction"); + mysql_mutex_assert_owner(&thd->LOCK_thd_data); + DBUG_ASSERT(thd->wsrep_conflict_state == MUST_REPLAY); + DBUG_ASSERT(wsrep_thd_trx_seqno(thd) > 0); + + WSREP_DEBUG("replaying SP transaction %llu", thd->thread_id); + close_thread_tables(thd); + if (thd->locked_tables_mode && thd->lock) + { + WSREP_DEBUG("releasing table lock for replaying (%u)", + thd->thread_id); + thd->locked_tables_list.unlock_locked_tables(thd); + thd->variables.option_bits&= ~(OPTION_TABLE_LOCK); + } + thd->release_transactional_locks(); + + mysql_mutex_unlock(&thd->LOCK_thd_data); + THD *replay_thd= new THD(true); + replay_thd->thread_stack= thd->thread_stack; + + struct wsrep_thd_shadow shadow; + wsrep_prepare_bf_thd(replay_thd, &shadow); + WSREP_DEBUG("replaying set for %p rgi %p", replay_thd, replay_thd->wsrep_rgi); replay_thd->wsrep_trx_meta= thd->wsrep_trx_meta; + replay_thd->wsrep_ws_handle= thd->wsrep_ws_handle; + replay_thd->wsrep_ws_handle.trx_id= WSREP_UNDEFINED_TRX_ID; + replay_thd->wsrep_conflict_state= REPLAYING; + + replay_thd->variables.option_bits|= OPTION_BEGIN; + replay_thd->server_status|= SERVER_STATUS_IN_TRANS; + + thd->reset_globals(); + replay_thd->store_globals(); + wsrep_status_t rcode= wsrep->replay_trx(wsrep, + &replay_thd->wsrep_ws_handle, + (void*) replay_thd); + + wsrep_return_from_bf_mode(replay_thd, &shadow); + replay_thd->reset_globals(); + delete replay_thd; + + mysql_mutex_lock(&thd->LOCK_thd_data); + + thd->store_globals(); + + switch (rcode) + { + case WSREP_OK: + { + thd->wsrep_conflict_state= NO_CONFLICT; + thd->killed= NOT_KILLED; + wsrep_status_t rcode= wsrep->post_commit(wsrep, &thd->wsrep_ws_handle); + if (rcode != WSREP_OK) + { + WSREP_WARN("Post commit failed for SP replay: thd: %u error: %d", + thd->thread_id, rcode); + } + /* As replaying the transaction was successful, an error must not + be returned to client, so we need to reset the error state of + the diagnostics area */ + thd->get_stmt_da()->reset_diagnostics_area(); + break; + } + case WSREP_TRX_FAIL: + { + thd->wsrep_conflict_state= ABORTED; + wsrep_status_t rcode= wsrep->post_rollback(wsrep, &thd->wsrep_ws_handle); + if (rcode != WSREP_OK) + { + WSREP_WARN("Post rollback failed for SP replay: thd: %u error: %d", + thd->thread_id, rcode); + } + if (thd->get_stmt_da()->is_set()) + { + thd->get_stmt_da()->reset_diagnostics_area(); + } + my_error(ER_LOCK_DEADLOCK, MYF(0)); + break; + } + default: + WSREP_ERROR("trx_replay failed for: %d, schema: %s, query: %s", + rcode, + (thd->db.str ? thd->db.str : "(null)"), + WSREP_QUERY(thd)); + /* we're now in inconsistent state, must abort */ + mysql_mutex_unlock(&thd->LOCK_thd_data); + unireg_abort(1); + break; + } + + wsrep_cleanup_transaction(thd); + + mysql_mutex_lock(&LOCK_wsrep_replaying); + wsrep_replaying--; + WSREP_DEBUG("replaying decreased: %d, thd: %u", + wsrep_replaying, thd->thread_id); + mysql_cond_broadcast(&COND_wsrep_replaying); + mysql_mutex_unlock(&LOCK_wsrep_replaying); + + DBUG_VOID_RETURN; +} + +void wsrep_replay_transaction(THD *thd) +{ + DBUG_ENTER("wsrep_replay_transaction"); + /* checking if BF trx must be replayed */ + if (thd->wsrep_conflict_state== MUST_REPLAY) { + DBUG_ASSERT(wsrep_thd_trx_seqno(thd)); + if (thd->wsrep_exec_mode!= REPL_RECV) { + if (thd->get_stmt_da()->is_sent()) + { + WSREP_ERROR("replay issue, thd has reported status already"); + } + + + /* + PS reprepare observer should have been removed already. + open_table() will fail if we have dangling observer here. + */ + DBUG_ASSERT(thd->m_reprepare_observer == NULL); + + struct da_shadow + { + enum Diagnostics_area::enum_diagnostics_status status; + ulonglong affected_rows; + ulonglong last_insert_id; + char message[MYSQL_ERRMSG_SIZE]; + }; + struct da_shadow da_status; + da_status.status= thd->get_stmt_da()->status(); + if (da_status.status == Diagnostics_area::DA_OK) + { + da_status.affected_rows= thd->get_stmt_da()->affected_rows(); + da_status.last_insert_id= thd->get_stmt_da()->last_insert_id(); + strmake(da_status.message, + thd->get_stmt_da()->message(), + sizeof(da_status.message)-1); + } + + thd->get_stmt_da()->reset_diagnostics_area(); + + thd->wsrep_conflict_state= REPLAYING; + mysql_mutex_unlock(&thd->LOCK_thd_data); + + thd->reset_for_next_command(); + thd->reset_killed(); + close_thread_tables(thd); + if (thd->locked_tables_mode && thd->lock) + { + WSREP_DEBUG("releasing table lock for replaying (%lld)", + (longlong) thd->thread_id); + thd->locked_tables_list.unlock_locked_tables(thd); + thd->variables.option_bits&= ~(OPTION_TABLE_LOCK); + } + thd->release_transactional_locks(); + /* + Replaying will call MYSQL_START_STATEMENT when handling + BEGIN Query_log_event so end statement must be called before + replaying. + */ + MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); + thd->m_statement_psi= NULL; + thd->m_digest= NULL; + thd_proc_info(thd, "WSREP replaying trx"); + WSREP_DEBUG("replay trx: %s %lld", + thd->query() ? thd->query() : "void", + (long long)wsrep_thd_trx_seqno(thd)); + struct wsrep_thd_shadow shadow; + wsrep_prepare_bf_thd(thd, &shadow); + + /* From trans_begin() */ + thd->variables.option_bits|= OPTION_BEGIN; + thd->server_status|= SERVER_STATUS_IN_TRANS; + + int rcode = wsrep->replay_trx(wsrep, + &thd->wsrep_ws_handle, + (void *)thd); + + wsrep_return_from_bf_mode(thd, &shadow); + if (thd->wsrep_conflict_state!= REPLAYING) + WSREP_WARN("lost replaying mode: %d", thd->wsrep_conflict_state ); + + mysql_mutex_lock(&thd->LOCK_thd_data); + + switch (rcode) + { + case WSREP_OK: + thd->wsrep_conflict_state= NO_CONFLICT; + wsrep->post_commit(wsrep, &thd->wsrep_ws_handle); + WSREP_DEBUG("trx_replay successful for: %lld %lld", + (longlong) thd->thread_id, (longlong) thd->real_id); + if (thd->get_stmt_da()->is_sent()) + { + WSREP_WARN("replay ok, thd has reported status"); + } + else if (thd->get_stmt_da()->is_set()) + { + if (thd->get_stmt_da()->status() != Diagnostics_area::DA_OK && + thd->get_stmt_da()->status() != Diagnostics_area::DA_OK_BULK) + { + WSREP_WARN("replay ok, thd has error status %d", + thd->get_stmt_da()->status()); + } + } + else + { + if (da_status.status == Diagnostics_area::DA_OK) + { + my_ok(thd, + da_status.affected_rows, + da_status.last_insert_id, + da_status.message); + } + else + { + my_ok(thd); + } + } + break; + case WSREP_TRX_FAIL: + if (thd->get_stmt_da()->is_sent()) + { + WSREP_ERROR("replay failed, thd has reported status"); + } + else + { + WSREP_DEBUG("replay failed, rolling back"); + } + thd->wsrep_conflict_state= ABORTED; + wsrep->post_rollback(wsrep, &thd->wsrep_ws_handle); + break; + default: + WSREP_ERROR("trx_replay failed for: %d, schema: %s, query: %s", + rcode, thd->get_db(), + thd->query() ? thd->query() : "void"); + /* we're now in inconsistent state, must abort */ + + /* http://bazaar.launchpad.net/~codership/codership-mysql/5.6/revision/3962#sql/wsrep_thd.cc */ + mysql_mutex_unlock(&thd->LOCK_thd_data); + + unireg_abort(1); + break; + } + + wsrep_cleanup_transaction(thd); + + mysql_mutex_lock(&LOCK_wsrep_replaying); + wsrep_replaying--; + WSREP_DEBUG("replaying decreased: %d, thd: %lld", + wsrep_replaying, (longlong) thd->thread_id); + mysql_cond_broadcast(&COND_wsrep_replaying); + mysql_mutex_unlock(&LOCK_wsrep_replaying); + } + } + DBUG_VOID_RETURN; +} +======= + thd->wsrep_rgi = NULL; + thd->set_row_count_func(shadow->row_count_func); +} + +void wsrep_replay_sp_transaction(THD* thd) +{ + DBUG_ENTER("wsrep_replay_sp_transaction"); + mysql_mutex_assert_owner(&thd->LOCK_thd_data); + DBUG_ASSERT(thd->wsrep_conflict_state == MUST_REPLAY); + DBUG_ASSERT(wsrep_thd_trx_seqno(thd) > 0); + + WSREP_DEBUG("replaying SP transaction %llu", thd->thread_id); + close_thread_tables(thd); + if (thd->locked_tables_mode && thd->lock) + { + WSREP_DEBUG("releasing table lock for replaying (%u)", + thd->thread_id); + thd->locked_tables_list.unlock_locked_tables(thd); + thd->variables.option_bits&= ~(OPTION_TABLE_LOCK); + } + thd->release_transactional_locks(); + + mysql_mutex_unlock(&thd->LOCK_thd_data); + THD *replay_thd= new THD(true); + replay_thd->thread_stack= thd->thread_stack; + + struct wsrep_thd_shadow shadow; + wsrep_prepare_bf_thd(replay_thd, &shadow); + WSREP_DEBUG("replaying set for %p rgi %p", replay_thd, replay_thd->wsrep_rgi); replay_thd->wsrep_trx_meta= thd->wsrep_trx_meta; + replay_thd->wsrep_ws_handle= thd->wsrep_ws_handle; + replay_thd->wsrep_ws_handle.trx_id= WSREP_UNDEFINED_TRX_ID; + replay_thd->wsrep_conflict_state= REPLAYING; + + replay_thd->variables.option_bits|= OPTION_BEGIN; + replay_thd->server_status|= SERVER_STATUS_IN_TRANS; + + thd->reset_globals(); + replay_thd->store_globals(); + wsrep_status_t rcode= wsrep->replay_trx(wsrep, + &replay_thd->wsrep_ws_handle, + (void*) replay_thd); + + wsrep_return_from_bf_mode(replay_thd, &shadow); + replay_thd->reset_globals(); + delete replay_thd; + + mysql_mutex_lock(&thd->LOCK_thd_data); + + thd->store_globals(); + + switch (rcode) + { + case WSREP_OK: + { + thd->wsrep_conflict_state= NO_CONFLICT; + thd->killed= NOT_KILLED; + wsrep_status_t rcode= wsrep->post_commit(wsrep, &thd->wsrep_ws_handle); + if (rcode != WSREP_OK) + { + WSREP_WARN("Post commit failed for SP replay: thd: %u error: %d", + thd->thread_id, rcode); + } + /* As replaying the transaction was successful, an error must not + be returned to client, so we need to reset the error state of + the diagnostics area */ + thd->get_stmt_da()->reset_diagnostics_area(); + break; + } + case WSREP_TRX_FAIL: + { + thd->wsrep_conflict_state= ABORTED; + wsrep_status_t rcode= wsrep->post_rollback(wsrep, &thd->wsrep_ws_handle); + if (rcode != WSREP_OK) + { + WSREP_WARN("Post rollback failed for SP replay: thd: %u error: %d", + thd->thread_id, rcode); + } + if (thd->get_stmt_da()->is_set()) + { + thd->get_stmt_da()->reset_diagnostics_area(); + } + my_error(ER_LOCK_DEADLOCK, MYF(0)); + break; + } + default: + WSREP_ERROR("trx_replay failed for: %d, schema: %s, query: %s", + rcode, + (thd->db.str ? thd->db.str : "(null)"), + WSREP_QUERY(thd)); + /* we're now in inconsistent state, must abort */ + mysql_mutex_unlock(&thd->LOCK_thd_data); + unireg_abort(1); + break; + } + + wsrep_cleanup_transaction(thd); + + mysql_mutex_lock(&LOCK_wsrep_replaying); + wsrep_replaying--; + WSREP_DEBUG("replaying decreased: %d, thd: %u", + wsrep_replaying, thd->thread_id); + mysql_cond_broadcast(&COND_wsrep_replaying); + mysql_mutex_unlock(&LOCK_wsrep_replaying); + + DBUG_VOID_RETURN; +} + +void wsrep_replay_transaction(THD *thd) +{ + DBUG_ENTER("wsrep_replay_transaction"); + /* checking if BF trx must be replayed */ + if (thd->wsrep_conflict_state== MUST_REPLAY) { + DBUG_ASSERT(wsrep_thd_trx_seqno(thd)); + if (thd->wsrep_exec_mode!= REPL_RECV) { + if (thd->get_stmt_da()->is_sent()) + { + WSREP_ERROR("replay issue, thd has reported status already"); + } + + + /* + PS reprepare observer should have been removed already. + open_table() will fail if we have dangling observer here. + */ + DBUG_ASSERT(thd->m_reprepare_observer == NULL); + + struct da_shadow + { + enum Diagnostics_area::enum_diagnostics_status status; + ulonglong affected_rows; + ulonglong last_insert_id; + char message[MYSQL_ERRMSG_SIZE]; + }; + struct da_shadow da_status; + da_status.status= thd->get_stmt_da()->status(); + if (da_status.status == Diagnostics_area::DA_OK) + { + da_status.affected_rows= thd->get_stmt_da()->affected_rows(); + da_status.last_insert_id= thd->get_stmt_da()->last_insert_id(); + strmake(da_status.message, + thd->get_stmt_da()->message(), + sizeof(da_status.message)-1); + } + + thd->get_stmt_da()->reset_diagnostics_area(); + + thd->wsrep_conflict_state= REPLAYING; + mysql_mutex_unlock(&thd->LOCK_thd_data); + + thd->reset_for_next_command(); + thd->reset_killed(); + close_thread_tables(thd); + if (thd->locked_tables_mode && thd->lock) + { + WSREP_DEBUG("releasing table lock for replaying (%lld)", + (longlong) thd->thread_id); + thd->locked_tables_list.unlock_locked_tables(thd); + thd->variables.option_bits&= ~(OPTION_TABLE_LOCK); + } + thd->release_transactional_locks(); + /* + Replaying will call MYSQL_START_STATEMENT when handling + BEGIN Query_log_event so end statement must be called before + replaying. + */ + MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); + thd->m_statement_psi= NULL; + thd->m_digest= NULL; + thd_proc_info(thd, "WSREP replaying trx"); + WSREP_DEBUG("replay trx: %s %lld", + thd->query() ? thd->query() : "void", + (long long)wsrep_thd_trx_seqno(thd)); + struct wsrep_thd_shadow shadow; + wsrep_prepare_bf_thd(thd, &shadow); + + /* From trans_begin() */ + thd->variables.option_bits|= OPTION_BEGIN; + thd->server_status|= SERVER_STATUS_IN_TRANS; + + /* Allow tests to block the replayer thread using the DBUG facilities */ +#ifdef ENABLED_DEBUG_SYNC + DBUG_EXECUTE_IF("sync.wsrep_replay_cb", + { + const char act[]= + "now " + "SIGNAL sync.wsrep_replay_cb_reached " + "WAIT_FOR signal.wsrep_replay_cb"; + DBUG_ASSERT(!debug_sync_set_action(thd, + STRING_WITH_LEN(act))); + };); +#endif /* ENABLED_DEBUG_SYNC */ + + int rcode = wsrep->replay_trx(wsrep, + &thd->wsrep_ws_handle, + (void *)thd); + + wsrep_return_from_bf_mode(thd, &shadow); + if (thd->wsrep_conflict_state!= REPLAYING) + WSREP_WARN("lost replaying mode: %d", thd->wsrep_conflict_state ); + + mysql_mutex_lock(&thd->LOCK_thd_data); + + switch (rcode) + { + case WSREP_OK: + thd->wsrep_conflict_state= NO_CONFLICT; + wsrep->post_commit(wsrep, &thd->wsrep_ws_handle); + WSREP_DEBUG("trx_replay successful for: %lld %lld", + (longlong) thd->thread_id, (longlong) thd->real_id); + if (thd->get_stmt_da()->is_sent()) + { + WSREP_WARN("replay ok, thd has reported status"); + } + else if (thd->get_stmt_da()->is_set()) + { + if (thd->get_stmt_da()->status() != Diagnostics_area::DA_OK && + thd->get_stmt_da()->status() != Diagnostics_area::DA_OK_BULK) + { + WSREP_WARN("replay ok, thd has error status %d", + thd->get_stmt_da()->status()); + } + } + else + { + if (da_status.status == Diagnostics_area::DA_OK) + { + my_ok(thd, + da_status.affected_rows, + da_status.last_insert_id, + da_status.message); + } + else + { + my_ok(thd); + } + } + break; + case WSREP_TRX_FAIL: + if (thd->get_stmt_da()->is_sent()) + { + WSREP_ERROR("replay failed, thd has reported status"); + } + else + { + WSREP_DEBUG("replay failed, rolling back"); + } + thd->wsrep_conflict_state= ABORTED; + wsrep->post_rollback(wsrep, &thd->wsrep_ws_handle); + break; + default: + WSREP_ERROR("trx_replay failed for: %d, schema: %s, query: %s", + rcode, thd->get_db(), + thd->query() ? thd->query() : "void"); + /* we're now in inconsistent state, must abort */ + + /* http://bazaar.launchpad.net/~codership/codership-mysql/5.6/revision/3962#sql/wsrep_thd.cc */ + mysql_mutex_unlock(&thd->LOCK_thd_data); + + unireg_abort(1); + break; + } + + wsrep_cleanup_transaction(thd); + + mysql_mutex_lock(&LOCK_wsrep_replaying); + wsrep_replaying--; + WSREP_DEBUG("replaying decreased: %d, thd: %lld", + wsrep_replaying, (longlong) thd->thread_id); + mysql_cond_broadcast(&COND_wsrep_replaying); + mysql_mutex_unlock(&LOCK_wsrep_replaying); + } + } + DBUG_VOID_RETURN; +} +>>>>>>> bb-10.3-release if(thd->has_thd_temporary_tables()) |