diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-04-08 10:36:41 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-04-08 10:36:41 +0300 |
commit | ccc06931c3c7be094f6dcddeb45589f06cf0c8af (patch) | |
tree | acfd8ed3cae2ee65cf6ddca6d96b907ea172d1dd /sql | |
parent | 9075973dbf2ef69e95d427e3a979be23435692e3 (diff) | |
parent | 476966b3fb05ce8c061a4b77a0ab0b722bb0d192 (diff) | |
download | mariadb-git-ccc06931c3c7be094f6dcddeb45589f06cf0c8af.tar.gz |
Merge 10.4 into 10.5
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 17 | ||||
-rw-r--r-- | sql/field.h | 1 | ||||
-rw-r--r-- | sql/log.cc | 18 | ||||
-rw-r--r-- | sql/opt_trace.cc | 21 | ||||
-rw-r--r-- | sql/rowid_filter.cc | 29 | ||||
-rw-r--r-- | sql/rowid_filter.h | 2 | ||||
-rw-r--r-- | sql/sql_partition.cc | 39 | ||||
-rw-r--r-- | sql/sql_select.cc | 2 | ||||
-rw-r--r-- | sql/sql_table.cc | 37 | ||||
-rw-r--r-- | sql/sql_update.cc | 1 | ||||
-rw-r--r-- | sql/table.h | 1 | ||||
-rw-r--r-- | sql/unireg.cc | 7 | ||||
-rw-r--r-- | sql/wsrep_high_priority_service.cc | 6 | ||||
-rw-r--r-- | sql/wsrep_thd.cc | 7 |
14 files changed, 125 insertions, 63 deletions
diff --git a/sql/field.cc b/sql/field.cc index a2cfbe65294..04c45dfb546 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -11077,3 +11077,20 @@ void Field::print_key_value_binary(String *out, const uchar* key, uint32 length) { out->append_semi_hex((const char*)key, length, charset()); } + + +Virtual_column_info* Virtual_column_info::clone(THD *thd) +{ + Virtual_column_info* dst= new (thd->mem_root) Virtual_column_info(*this); + if (!dst) + return NULL; + if (expr) + { + dst->expr= expr->get_copy(thd); + if (!dst->expr) + return NULL; + } + if (!thd->make_lex_string(&dst->name, name.str, name.length)) + return NULL; + return dst; +}; diff --git a/sql/field.h b/sql/field.h index 05955db2a58..d709a84e0fe 100644 --- a/sql/field.h +++ b/sql/field.h @@ -596,6 +596,7 @@ public: name.str= NULL; name.length= 0; }; + Virtual_column_info* clone(THD *thd); ~Virtual_column_info() {}; enum_vcol_info_type get_vcol_type() const { diff --git a/sql/log.cc b/sql/log.cc index 72833c7c173..fce768b2e4c 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2408,9 +2408,6 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv) int error= 1; DBUG_ENTER("binlog_savepoint_set"); - if (wsrep_emulate_bin_log) - DBUG_RETURN(0); - char buf[1024]; String log_query(buf, sizeof(buf), &my_charset_bin); @@ -2443,9 +2440,6 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv) { DBUG_ENTER("binlog_savepoint_rollback"); - if (wsrep_emulate_bin_log) - DBUG_RETURN(0); - /* Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some non-transactional table. Otherwise, truncate the binlog cache starting @@ -11011,18 +11005,20 @@ void wsrep_register_binlog_handler(THD *thd, bool trx) back a statement or a transaction. However, notifications do not happen if the binary log is set as read/write. */ - //binlog_cache_mngr *cache_mngr= thd_get_cache_mngr(thd); binlog_cache_mngr *cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); /* cache_mngr may be missing e.g. in mtr test ev51914.test */ - if (cache_mngr && cache_mngr->trx_cache.get_prev_position() == MY_OFF_T_UNDEF) + if (cache_mngr) { /* Set an implicit savepoint in order to be able to truncate a trx-cache. */ - my_off_t pos= 0; - binlog_trans_log_savepos(thd, &pos); - cache_mngr->trx_cache.set_prev_position(pos); + if (cache_mngr->trx_cache.get_prev_position() == MY_OFF_T_UNDEF) + { + my_off_t pos= 0; + binlog_trans_log_savepos(thd, &pos); + cache_mngr->trx_cache.set_prev_position(pos); + } /* Set callbacks in order to be able to call commmit or rollback. diff --git a/sql/opt_trace.cc b/sql/opt_trace.cc index a8676eec411..ddec6d5ed2d 100644 --- a/sql/opt_trace.cc +++ b/sql/opt_trace.cc @@ -24,6 +24,8 @@ #include "my_json_writer.h" #include "sp_head.h" +#include "rowid_filter.h" + const char I_S_table_name[]= "OPTIMIZER_TRACE"; /** @@ -664,14 +666,17 @@ void print_best_access_for_table(THD *thd, POSITION *pos, { DBUG_ASSERT(thd->trace_started()); - Json_writer_object trace_best_access(thd, "chosen_access_method"); - trace_best_access.add("type", type == JT_ALL ? "scan" : - join_type_str[type]); - trace_best_access.add("records", pos->records_read); - trace_best_access.add("cost", pos->read_time); - trace_best_access.add("uses_join_buffering", pos->use_join_buffer); - trace_best_access.add("filter_used", - pos->range_rowid_filter_info != NULL); + Json_writer_object obj(thd, "chosen_access_method"); + obj.add("type", type == JT_ALL ? "scan" : join_type_str[type]); + obj.add("records", pos->records_read); + obj.add("cost", pos->read_time); + obj.add("uses_join_buffering", pos->use_join_buffer); + if (pos->range_rowid_filter_info) + { + uint key_no= pos->range_rowid_filter_info->key_no; + obj.add("rowid_filter_key", + pos->table->table->key_info[key_no].name); + } } diff --git a/sql/rowid_filter.cc b/sql/rowid_filter.cc index d6c633aa3e2..1d9363693cb 100644 --- a/sql/rowid_filter.cc +++ b/sql/rowid_filter.cc @@ -20,6 +20,7 @@ #include "opt_range.h" #include "rowid_filter.h" #include "sql_select.h" +#include "opt_trace.h" inline @@ -403,9 +404,37 @@ void TABLE::init_cost_info_for_usable_range_rowid_filters(THD *thd) } prune_range_rowid_filters(); + + if (unlikely(thd->trace_started())) + trace_range_rowid_filters(thd); } +void TABLE::trace_range_rowid_filters(THD *thd) const +{ + if (!range_rowid_filter_cost_info_elems) + return; + + Range_rowid_filter_cost_info **p= range_rowid_filter_cost_info_ptr; + Range_rowid_filter_cost_info **end= p + range_rowid_filter_cost_info_elems; + + Json_writer_object js_obj(thd); + js_obj.add_table_name(this); + Json_writer_array js_arr(thd, "rowid_filters"); + + for (; p < end; p++) + (*p)->trace_info(thd); +} + + +void Range_rowid_filter_cost_info::trace_info(THD *thd) +{ + Json_writer_object js_obj(thd); + js_obj.add("key", table->key_info[key_no].name); + js_obj.add("build_cost", b); + js_obj.add("rows", est_elements); +} + /** @brief Choose the best range filter for the given access of the table diff --git a/sql/rowid_filter.h b/sql/rowid_filter.h index a9930dcbca8..467b6884ca6 100644 --- a/sql/rowid_filter.h +++ b/sql/rowid_filter.h @@ -452,6 +452,8 @@ public: double get_a() { return a; } + void trace_info(THD *thd); + friend void TABLE::prune_range_rowid_filters(); diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index ce2ee1b5aa2..ef8ef5114a8 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -6751,9 +6751,9 @@ static void release_log_entries(partition_info *part_info) alter_partition_lock_handling() lpt Struct carrying parameters RETURN VALUES - NONE + true on error */ -static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt) +static bool alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt) { THD *thd= lpt->thd; @@ -6767,23 +6767,9 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt) lpt->table= 0; lpt->table_list->table= 0; if (thd->locked_tables_mode) - { - Diagnostics_area *stmt_da= NULL; - Diagnostics_area tmp_stmt_da(true); - - if (unlikely(thd->is_error())) - { - /* reopen might fail if we have a previous error, use a temporary da. */ - stmt_da= thd->get_stmt_da(); - thd->set_stmt_da(&tmp_stmt_da); - } + return thd->locked_tables_list.reopen_tables(thd, false); - if (unlikely(thd->locked_tables_list.reopen_tables(thd, false))) - sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE"); - - if (stmt_da) - thd->set_stmt_da(stmt_da); - } + return false; } @@ -6984,6 +6970,8 @@ err_exclusive_lock: thd->set_stmt_da(&tmp_stmt_da); } + /* NB: error status is not needed here, the statement fails with + the original error. */ if (unlikely(thd->locked_tables_list.reopen_tables(thd, false))) sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE"); @@ -7207,13 +7195,14 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, ERROR_INJECT_ERROR("fail_drop_partition_8") || (write_log_completed(lpt, FALSE), FALSE) || ERROR_INJECT_CRASH("crash_drop_partition_9") || - ERROR_INJECT_ERROR("fail_drop_partition_9") || - (alter_partition_lock_handling(lpt), FALSE)) + ERROR_INJECT_ERROR("fail_drop_partition_9")) { handle_alter_part_error(lpt, action_completed, TRUE, frm_install, close_table_on_failure); goto err; } + if (alter_partition_lock_handling(lpt)) + goto err; } else if ((alter_info->partition_flags & ALTER_PARTITION_ADD) && (part_info->part_type == RANGE_PARTITION || @@ -7284,13 +7273,14 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, ERROR_INJECT_ERROR("fail_add_partition_9") || (write_log_completed(lpt, FALSE), FALSE) || ERROR_INJECT_CRASH("crash_add_partition_10") || - ERROR_INJECT_ERROR("fail_add_partition_10") || - (alter_partition_lock_handling(lpt), FALSE)) + ERROR_INJECT_ERROR("fail_add_partition_10")) { handle_alter_part_error(lpt, action_completed, FALSE, frm_install, close_table_on_failure); goto err; } + if (alter_partition_lock_handling(lpt)) + goto err; } else { @@ -7389,13 +7379,14 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, ERROR_INJECT_ERROR("fail_change_partition_11") || (write_log_completed(lpt, FALSE), FALSE) || ERROR_INJECT_CRASH("crash_change_partition_12") || - ERROR_INJECT_ERROR("fail_change_partition_12") || - (alter_partition_lock_handling(lpt), FALSE)) + ERROR_INJECT_ERROR("fail_change_partition_12")) { handle_alter_part_error(lpt, action_completed, FALSE, frm_install, close_table_on_failure); goto err; } + if (alter_partition_lock_handling(lpt)) + goto err; } downgrade_mdl_if_lock_tables_mode(thd, mdl_ticket, MDL_SHARED_NO_READ_WRITE); /* diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 9f4ddb4f357..129dae9eedb 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7818,6 +7818,8 @@ best_access_path(JOIN *join, filter->get_cmp_gain(rows); tmp-= filter->get_adjusted_gain(rows) - filter->get_cmp_gain(rows); DBUG_ASSERT(tmp >= 0); + trace_access_idx.add("rowid_filter_key", + s->table->key_info[filter->key_no].name); } } trace_access_idx.add("rows", records).add("cost", tmp); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 58ca31bf933..6ab224abee5 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4383,6 +4383,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, const Virtual_column_info *dup_check; while ((dup_check= dup_it++) && dup_check != check) { + if (!dup_check->name.length || dup_check->automatic_name) + continue; if (!lex_string_cmp(system_charset_info, &check->name, &dup_check->name)) { @@ -8703,8 +8705,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, key_part_length= 0; // Use whole field } key_part_length /= kfield->charset()->mbmaxlen; - key_parts.push_back(new Key_part_spec(&cfield->field_name, - key_part_length), + key_parts.push_back(new (thd->mem_root) Key_part_spec( + &cfield->field_name, key_part_length), thd->mem_root); } if (table->s->tmp_table == NO_TMP_TABLE) @@ -8770,7 +8772,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, tmp_name.str= key_name; tmp_name.length= strlen(key_name); /* We dont need LONG_UNIQUE_HASH_FIELD flag because it will be autogenerated */ - key= new Key(key_type, &tmp_name, &key_create_info, + key= new (thd->mem_root) Key(key_type, &tmp_name, &key_create_info, MY_TEST(key_info->flags & HA_GENERATED_KEY), &key_parts, key_info->option_list, DDL_options()); key->without_overlaps= key_info->without_overlaps; @@ -8850,26 +8852,37 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } } + // NB: `check` is TABLE resident, we must keep it intact. + if (keep) + { + check= check->clone(thd); + if (!check) + { + my_error(ER_OUT_OF_RESOURCES, MYF(0)); + goto err; + } + } + if (share->period.constr_name.streq(check->name.str)) { - if (!drop_period && !keep) + if (drop_period) + { + keep= false; + } + else if(!keep) { my_error(ER_PERIOD_CONSTRAINT_DROP, MYF(0), check->name.str, share->period.name.str); goto err; } - keep= keep && !drop_period; - - DBUG_ASSERT(create_info->period_info.constr == NULL || drop_period); - - if (keep) + else { - Item *expr_copy= check->expr->get_copy(thd); - check= new Virtual_column_info(); - check->expr= expr_copy; + DBUG_ASSERT(create_info->period_info.constr == NULL); create_info->period_info.constr= check; + create_info->period_info.constr->automatic_name= true; } } + /* see if the constraint depends on *only* on dropped fields */ if (keep && dropped_fields) { diff --git a/sql/sql_update.cc b/sql/sql_update.cc index c3ade4288d2..2ca03620b17 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -463,6 +463,7 @@ int mysql_update(THD *thd, my_error(ER_NOT_CONSTANT_EXPRESSION, MYF(0), "FOR PORTION OF"); DBUG_RETURN(true); } + table->no_cache= true; } old_covering_keys= table->covering_keys; // Keys used in WHERE diff --git a/sql/table.h b/sql/table.h index ce8f204f3ac..ddd33142fd7 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1591,6 +1591,7 @@ public: void init_cost_info_for_usable_range_rowid_filters(THD *thd); void prune_range_rowid_filters(); + void trace_range_rowid_filters(THD *thd) const; Range_rowid_filter_cost_info * best_range_rowid_filter_for_partial_join(uint access_key_no, double records, diff --git a/sql/unireg.cc b/sql/unireg.cc index 79403ff339d..6860d2c6347 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -57,6 +57,13 @@ static bool make_empty_rec(THD *, uchar *, uint, List<Create_field> &, uint, */ static uchar *extra2_write_len(uchar *pos, size_t len) { + /* TODO: should be + if (len > 0 && len <= 255) + *pos++= (uchar)len; + ... + because extra2_read_len() uses 0 for 2-byte lengths. + extra2_str_size() must be fixed too. + */ if (len <= 255) *pos++= (uchar)len; else diff --git a/sql/wsrep_high_priority_service.cc b/sql/wsrep_high_priority_service.cc index d73b9cb09ce..992883aa797 100644 --- a/sql/wsrep_high_priority_service.cc +++ b/sql/wsrep_high_priority_service.cc @@ -478,11 +478,15 @@ Wsrep_applier_service::Wsrep_applier_service(THD* thd) thd->wsrep_cs().open(wsrep::client_id(thd->thread_id)); thd->wsrep_cs().before_command(); thd->wsrep_cs().debug_log_level(wsrep_debug); - + if (!thd->slave_thread) + thd->system_thread_info.rpl_sql_info= + new rpl_sql_thread_info(thd->wsrep_rgi->rli->mi->rpl_filter); } Wsrep_applier_service::~Wsrep_applier_service() { + if (!m_thd->slave_thread) + delete m_thd->system_thread_info.rpl_sql_info; m_thd->wsrep_cs().after_command_before_result(); m_thd->wsrep_cs().after_command_after_result(); m_thd->wsrep_cs().close(); diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index b605ff0496d..94d01b273c5 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -53,11 +53,6 @@ static void wsrep_replication_process(THD *thd, Wsrep_applier_service applier_service(thd); - /* thd->system_thread_info.rpl_sql_info isn't initialized. */ - if (!thd->slave_thread) - thd->system_thread_info.rpl_sql_info= - new rpl_sql_thread_info(thd->wsrep_rgi->rli->mi->rpl_filter); - WSREP_INFO("Starting applier thread %llu", thd->thread_id); enum wsrep::provider::status ret= Wsrep_server_state::get_provider().run_applier(&applier_service); @@ -68,8 +63,6 @@ static void wsrep_replication_process(THD *thd, mysql_cond_broadcast(&COND_wsrep_slave_threads); mysql_mutex_unlock(&LOCK_wsrep_slave_threads); - if (!thd->slave_thread) - delete thd->system_thread_info.rpl_sql_info; delete thd->wsrep_rgi->rli->mi; delete thd->wsrep_rgi->rli; |