diff options
author | Sergei Golubchik <serg@mariadb.org> | 2021-02-12 17:44:22 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2021-02-12 17:44:22 +0100 |
commit | 00a313ecf329098d4b31a42030b9b5c6f80a6031 (patch) | |
tree | f4983a6629b04563c48fa7276686dfc2187efb5f /sql | |
parent | ef5adf520760536c7396bdfe884fc509ac065694 (diff) | |
parent | 691f93d6d17603f11a0c90f64e94b7ce9d187db4 (diff) | |
download | mariadb-git-00a313ecf329098d4b31a42030b9b5c6f80a6031.tar.gz |
Merge branch 'bb-10.3-release' into bb-10.4-release
Note, the fix for "MDEV-23328 Server hang due to Galera lock conflict resolution"
was null-merged. 10.4 version of the fix is coming up separately
Diffstat (limited to 'sql')
52 files changed, 529 insertions, 544 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..e70cef5742e 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -859,6 +859,7 @@ static my_bool kill_handlerton(THD *thd, plugin_ref plugin, { handlerton *hton= plugin_hton(plugin); + mysql_mutex_assert_owner(&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); @@ -5211,6 +5212,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..19918361dd7 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(THD *thd) +{ + longlong tmp = (*ref)->val_time_packed(thd); + null_value= (*ref)->null_value; + return tmp; +} + + +longlong Item_direct_ref::val_datetime_packed(THD *thd) +{ + longlong tmp = (*ref)->val_datetime_packed(thd); + 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..3f117eb6d6c 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 val_native(THD *thd, Native *to); bool is_null(); bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate); + longlong val_datetime_packed(THD *); + longlong val_time_packed(THD *); 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(THD *thd) + { + if (check_null_ref()) + return 0; + else + return Item_direct_ref::val_time_packed(thd); + } + longlong val_datetime_packed(THD *thd) + { + if (check_null_ref()) + return 0; + else + return Item_direct_ref::val_datetime_packed(thd); + } 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..1798d3039fa 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); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a74fb4326e4..d4b49047046 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}, @@ -1905,6 +1901,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 +2137,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 +4550,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 +5247,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 +5260,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..f4d0d891a0f 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..68734bcbef8 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 @@ -15658,8 +15657,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 +15678,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 +15773,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 +15802,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 +15810,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)); @@ -16043,8 +16042,8 @@ void print_range_for_non_indexed_field(String *out, Field *field, KEY_MULTI_RANGE *range) { 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 (range->start_key.length) { @@ -16059,7 +16058,7 @@ void print_range_for_non_indexed_field(String *out, Field *field, print_max_range_operator(out, range->end_key.flag); field->print_key_part_value(out, range->end_key.key, field->key_length()); } - 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); } @@ -16126,8 +16125,8 @@ static void print_key_value(String *out, const KEY_PART_INFO *key_part, StringBuffer<128> tmp(system_charset_info); TABLE *table= field->table; uint store_length; - 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); const uchar *key_end= key+used_length; for (; key < key_end; key+=store_length, key_part++) @@ -16140,7 +16139,7 @@ static void print_key_value(String *out, const KEY_PART_INFO *key_part, if (key + store_length < key_end) out->append(STRING_WITH_LEN(",")); } - 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); out->append(STRING_WITH_LEN(")")); } 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..35901cb5263 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -4,6 +4,7 @@ #include "rpl_mi.h" #include "sql_parse.h" #include "debug_sync.h" +#include "sql_repl.h" #include "wsrep_mysqld.h" #ifdef WITH_WSREP #include "wsrep_trans_observer.h" @@ -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/service_wsrep.cc b/sql/service_wsrep.cc index 4fc927cfd86..f0a4cf81c02 100644 --- a/sql/service_wsrep.cc +++ b/sql/service_wsrep.cc @@ -37,6 +37,16 @@ extern "C" void wsrep_thd_UNLOCK(const THD *thd) mysql_mutex_unlock(&thd->LOCK_thd_data); } +extern "C" void wsrep_thd_kill_LOCK(const THD *thd) +{ + mysql_mutex_lock(&thd->LOCK_thd_kill); +} + +extern "C" void wsrep_thd_kill_UNLOCK(const THD *thd) +{ + mysql_mutex_unlock(&thd->LOCK_thd_kill); +} + extern "C" const char* wsrep_thd_client_state_str(const THD *thd) { return wsrep::to_c_string(thd->wsrep_cs().state()); diff --git a/sql/slave.cc b/sql/slave.cc index 9d4049c6452..40c09604745 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" ":"") @@ -362,10 +363,33 @@ end: return err; } +static THD *new_bg_THD() +{ + THD *thd= new THD(next_thread_id()); + thd->thread_stack= (char*) &thd; + thd->store_globals(); + thd->system_thread = SYSTEM_THREAD_SLAVE_BACKGROUND; + thd->security_ctx->skip_grants(); + thd->set_command(COM_DAEMON); + thd->variables.wsrep_on= 0; + return thd; +} -static void -handle_gtid_pos_auto_create_request(THD *thd, void *hton) +static void bg_gtid_delete_pending(void *) { + THD *thd= new_bg_THD(); + + rpl_slave_state::list_element *list; + list= rpl_global_gtid_slave_state->gtid_grab_pending_delete_list(); + rpl_global_gtid_slave_state->gtid_delete_pending(thd, &list); + if (list) + rpl_global_gtid_slave_state->put_back_list(list); + delete thd; +} + +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 +401,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 +445,7 @@ 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_bg_THD(); err= gtid_pos_table_creation(thd, engine, &table_name); if (err) { @@ -449,46 +473,16 @@ handle_gtid_pos_auto_create_request(THD *thd, void *hton) mysql_mutex_unlock(&rpl_global_gtid_slave_state->LOCK_slave_state); end: + delete thd; if (engine) plugin_unlock(NULL, engine); } - -static bool slave_background_thread_running; -static bool slave_background_thread_stop; static bool slave_background_thread_gtid_loaded; -static struct slave_background_kill_t { - slave_background_kill_t *next; - THD *to_kill; -} *slave_background_kill_list; - -static struct slave_background_gtid_pos_create_t { - slave_background_gtid_pos_create_t *next; - void *hton; -} *slave_background_gtid_pos_create_list; - -static volatile bool slave_background_gtid_pending_delete_flag; - - -pthread_handler_t -handle_slave_background(void *arg __attribute__((unused))) +static void bg_rpl_load_gtid_slave_state(void *) { - THD *thd; - PSI_stage_info old_stage; - bool stop; - - my_thread_init(); - thd= new THD(next_thread_id()); - thd->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 *thd= new_bg_THD(); thd_proc_info(thd, "Loading slave GTID position from table"); if (rpl_load_gtid_slave_state(thd)) sql_print_warning("Failed to load slave replication state from table " @@ -497,207 +491,62 @@ handle_slave_background(void *arg __attribute__((unused))) thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message()); - mysql_mutex_lock(&LOCK_slave_background); + // hijacking global_rpl_thread_pool cond here - it's only once on startup + mysql_mutex_lock(&global_rpl_thread_pool.LOCK_rpl_thread_pool); slave_background_thread_gtid_loaded= true; - mysql_cond_broadcast(&COND_slave_background); - - THD_STAGE_INFO(thd, stage_slave_background_process_request); - do - { - slave_background_kill_t *kill_list; - slave_background_gtid_pos_create_t *create_list; - bool pending_deletes; - - thd->ENTER_COND(&COND_slave_background, &LOCK_slave_background, - &stage_slave_background_wait_request, - &old_stage); - for (;;) - { - stop= thd->killed || slave_background_thread_stop; - kill_list= slave_background_kill_list; - create_list= slave_background_gtid_pos_create_list; - pending_deletes= slave_background_gtid_pending_delete_flag; - if (stop || kill_list || create_list || pending_deletes) - break; - mysql_cond_wait(&COND_slave_background, &LOCK_slave_background); - } - - slave_background_kill_list= NULL; - slave_background_gtid_pos_create_list= NULL; - slave_background_gtid_pending_delete_flag= false; - 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; - } - - if (pending_deletes) - { - rpl_slave_state::list_element *list; - - slave_background_gtid_pending_delete_flag= false; - list= rpl_global_gtid_slave_state->gtid_grab_pending_delete_list(); - rpl_global_gtid_slave_state->gtid_delete_pending(thd, &list); - if (list) - rpl_global_gtid_slave_state->put_back_list(list); - } - - mysql_mutex_lock(&LOCK_slave_background); - } while (!stop); - - slave_background_thread_running= false; - mysql_cond_broadcast(&COND_slave_background); - mysql_mutex_unlock(&LOCK_slave_background); - + mysql_cond_signal(&global_rpl_thread_pool.COND_rpl_thread_pool); + mysql_mutex_unlock(&global_rpl_thread_pool.LOCK_rpl_thread_pool); delete thd; - - my_thread_end(); - return 0; } +static void bg_slave_kill(void *victim) +{ + THD *to_kill= (THD *)victim; + to_kill->awake(KILL_CONNECTION); + mysql_mutex_lock(&to_kill->LOCK_wakeup_ready); + to_kill->rgi_slave->killed_for_retry= rpl_group_info::RETRY_KILL_KILLED; + mysql_cond_broadcast(&to_kill->COND_wakeup_ready); + mysql_mutex_unlock(&to_kill->LOCK_wakeup_ready); +} - -void -slave_background_kill_request(THD *to_kill) +void slave_background_kill_request(THD *to_kill) { if (to_kill->rgi_slave->killed_for_retry) return; // Already deadlock killed. - slave_background_kill_t *p= - (slave_background_kill_t *)my_malloc(sizeof(*p), MYF(MY_WME)); - if (p) - { - p->to_kill= to_kill; - to_kill->rgi_slave->killed_for_retry= - rpl_group_info::RETRY_KILL_PENDING; - mysql_mutex_lock(&LOCK_slave_background); - p->next= slave_background_kill_list; - slave_background_kill_list= p; - mysql_cond_signal(&COND_slave_background); - mysql_mutex_unlock(&LOCK_slave_background); - } + to_kill->rgi_slave->killed_for_retry= rpl_group_info::RETRY_KILL_PENDING; + mysql_manager_submit(bg_slave_kill, to_kill); } - /* This function must only be called from a slave SQL thread (or worker thread), to ensure that the table_entry will not go away before we can lock the LOCK_slave_state. */ -void -slave_background_gtid_pos_create_request( +void slave_background_gtid_pos_create_request( rpl_slave_state::gtid_pos_table *table_entry) { - slave_background_gtid_pos_create_t *p; - if (table_entry->state != rpl_slave_state::GTID_POS_AUTO_CREATE) return; - p= (slave_background_gtid_pos_create_t *)my_malloc(sizeof(*p), MYF(MY_WME)); - if (!p) - return; mysql_mutex_lock(&rpl_global_gtid_slave_state->LOCK_slave_state); if (table_entry->state != rpl_slave_state::GTID_POS_AUTO_CREATE) { - my_free(p); mysql_mutex_unlock(&rpl_global_gtid_slave_state->LOCK_slave_state); return; } table_entry->state= rpl_slave_state::GTID_POS_CREATE_REQUESTED; mysql_mutex_unlock(&rpl_global_gtid_slave_state->LOCK_slave_state); - p->hton= table_entry->table_hton; - mysql_mutex_lock(&LOCK_slave_background); - p->next= slave_background_gtid_pos_create_list; - slave_background_gtid_pos_create_list= p; - mysql_cond_signal(&COND_slave_background); - mysql_mutex_unlock(&LOCK_slave_background); + mysql_manager_submit(bg_gtid_pos_auto_create, table_entry->table_hton); } /* - Request the slave background thread to delete no longer used rows from the + Request the manager thread to delete no longer used rows from the mysql.gtid_slave_pos* tables. - - This is called from time-critical rpl_slave_state::update(), so we avoid - taking any locks here. This means we may race with the background thread - to occasionally lose a signal. This is not a problem; any pending rows to - be deleted will just be deleted a bit later as part of the next batch. -*/ -void -slave_background_gtid_pending_delete_request(void) -{ - slave_background_gtid_pending_delete_flag= true; - mysql_cond_signal(&COND_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() +void slave_background_gtid_pending_delete_request(void) { - 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_delete_pending, NULL); } @@ -712,12 +561,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. @@ -1446,7 +1302,6 @@ void slave_prepare_for_shutdown() // It's safe to destruct worker pool now when // all driver threads are gone. global_rpl_thread_pool.deactivate(); - stop_slave_background_thread(); } /* @@ -1477,8 +1332,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 +4590,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 +4910,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 +4923,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 +5526,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..5c1ad49c9de 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,30 +1515,15 @@ 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) - { - if (have_mutex) - { - mysql_mutex_assert_owner(static_cast<mysql_mutex_t*> - (m_wsrep_mutex.native())); - // Below wsrep-lib function will not acquire any mutexes - wsrep::unique_lock<wsrep::mutex> lock(m_wsrep_mutex, std::adopt_lock); - wsrep_cs().cleanup(lock); - lock.release(); - } - else - wsrep_cs().cleanup(); - } + wsrep_cs().cleanup(); wsrep_client_thread= false; #endif /* WITH_WSREP */ @@ -1611,28 +1599,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 +1607,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 +1619,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); } /* @@ -1708,6 +1672,17 @@ THD::~THD() if (!status_in_global) add_status_to_global(); + /* + Other threads may have a lock on 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 delete + */ + mysql_mutex_lock(&LOCK_thd_kill); + mysql_mutex_unlock(&LOCK_thd_kill); + +#ifdef WITH_WSREP + delete wsrep_rgi; +#endif if (!free_connection_done) free_connection(); @@ -5085,6 +5060,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..77bde414b31 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2268,7 +2268,7 @@ public: - mysys_var (used by KILL statement and shutdown). - Also ensures that THD is not deleted while mutex is hold */ - mysql_mutex_t LOCK_thd_kill; + mutable mysql_mutex_t LOCK_thd_kill; /* all prepared statements and cursors of this connection */ Statement_map stmt_map; @@ -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..eb5532f5d59 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -22,10 +22,11 @@ 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 + 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 "mariadb.h" #undef SHOW_always_last @@ -204,4 +205,3 @@ extern void sync_dynamic_session_variables(THD* thd, bool global_lock); extern void wsrep_plugins_pre_init(); extern void wsrep_plugins_post_init(); #endif /* WITH_WSREP */ - diff --git a/sql/sql_plugin_services.ic b/sql/sql_plugin_services.ic index 69e57de5c8b..a8b70e294e1 100644 --- a/sql/sql_plugin_services.ic +++ b/sql/sql_plugin_services.ic @@ -175,7 +175,9 @@ static struct wsrep_service_st wsrep_handler = { wsrep_commit_ordered, wsrep_thd_is_applying, wsrep_thd_set_wsrep_aborter, - wsrep_report_bf_lock_wait + wsrep_report_bf_lock_wait, + wsrep_thd_kill_LOCK, + wsrep_thd_kill_UNLOCK }; static struct thd_specifics_service_st thd_specifics_handler= @@ -245,4 +247,3 @@ static struct st_service_ref list_of_services[]= { "wsrep_service", VERSION_wsrep, &wsrep_handler }, { "json_service", VERSION_json, &json_handler } }; - 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..7d9517ff1f2 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,7 +2318,7 @@ 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); @@ -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 50fe0eb3a6f..ac1984a074c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4071,8 +4071,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; @@ -4116,7 +4115,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 */ @@ -4395,7 +4394,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, @@ -5296,6 +5296,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, @@ -5333,6 +5336,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 8e432c54b15..8340901175a 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -1022,6 +1022,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 */ @@ -1040,7 +1042,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_dummy.cc b/sql/wsrep_dummy.cc index c4dbd8c450f..2503a97590b 100644 --- a/sql/wsrep_dummy.cc +++ b/sql/wsrep_dummy.cc @@ -59,6 +59,12 @@ void wsrep_thd_LOCK(const THD *) void wsrep_thd_UNLOCK(const THD *) { } +void wsrep_thd_kill_LOCK(const THD *) +{ } + +void wsrep_thd_kill_UNLOCK(const THD *) +{ } + const char *wsrep_thd_conflict_state_str(THD *) { return 0; } 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..26cfa4c58c4 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -22,7 +22,6 @@ #include "rpl_rli.h" #include "log_event.h" #include "sql_parse.h" -#include "sql_base.h" // close_thread_tables() #include "mysqld.h" // start_wsrep_THD(); #include "wsrep_applier.h" // start_wsrep_THD(); #include "mysql/service_wsrep.h" |