diff --git a/storage/tianchi/datatype_cnvrt_4_index_search.cc b/storage/tianchi/datatype_cnvrt_4_index_search.cc index a5b7696251aca056d56751a88d7bbd5b641d4f21..6f104f26480184ac87e2f9e5240302e12ac98ff0 100644 --- a/storage/tianchi/datatype_cnvrt_4_index_search.cc +++ b/storage/tianchi/datatype_cnvrt_4_index_search.cc @@ -94,7 +94,7 @@ static void tse_index_make_up_key_length(int *key, uint8_t **origin_key, uint32_ } int tse_fill_index_key_info(TABLE *table, const uchar *key, uint key_len, const key_range *end_range, - index_key_info_t *index_key_info, bool is_reading_range) { + index_key_info_t *index_key_info, bool index_skip_scan) { const uchar *my_key = nullptr; const uchar *end_key = key + key_len; if (end_range != nullptr) { @@ -116,7 +116,7 @@ int tse_fill_index_key_info(TABLE *table, const uchar *key, uint key_len, const &index_key_info->key_info[index_key_info->key_num].left_key_len, &index_key_info->key_info[index_key_info->key_num].is_key_null); - if (is_reading_range && end_range != nullptr && my_key < end_range->key + end_range->length) { + if (!index_skip_scan && end_range != nullptr && my_key < end_range->key + end_range->length) { tse_convert_mysql_key_to_cantian(key_part, my_key, end_range->length, &data_field_len, &index_key_info->key_info[index_key_info->key_num].right_key, &index_key_info->key_info[index_key_info->key_num].right_key_len, diff --git a/storage/tianchi/datatype_cnvrt_4_index_search.h b/storage/tianchi/datatype_cnvrt_4_index_search.h index 39216bf49a21e82972afcf586724460a2d94116d..aed10e22ae0b9a6529e11a6a00688c9022937bef 100644 --- a/storage/tianchi/datatype_cnvrt_4_index_search.h +++ b/storage/tianchi/datatype_cnvrt_4_index_search.h @@ -20,6 +20,6 @@ #include "decimal_convert.h" int tse_fill_index_key_info(TABLE *table, const uchar *key, uint key_len, const key_range *end_range, - index_key_info_t *index_key_info, bool is_reading_range); + index_key_info_t *index_key_info, bool index_skip_scan); int tse_convert_index_datatype(TABLE *table, index_key_info_t *index_key_info, bool has_right_key, dec4_t *data); diff --git a/storage/tianchi/ha_tse.cc b/storage/tianchi/ha_tse.cc index c46252e9f0e6dbaf0b0c3c1826bd3f066e1f4c1e..932f402a1167dd3daa31d6c7de1563598ea57d8f 100644 --- a/storage/tianchi/ha_tse.cc +++ b/storage/tianchi/ha_tse.cc @@ -124,6 +124,8 @@ #include "sql/sql_backup_lock.h" #include "ctc_meta_data.h" #include "sql/mysqld.h" +#include "sql/opt_range.h" // QUICK_SELECT_I +#include "sql/sql_executor.h" // class QEP_TAB //------------------------------------------------------------------------------// // SYSTEM VARIABLES // @@ -160,8 +162,8 @@ int32_t ctc_metadata_normalization = (int32_t)metadata_switchs::DEFAULT; static MYSQL_SYSVAR_INT(metadata_normalization, ctc_metadata_normalization, PLUGIN_VAR_READONLY, "Option for Mysql-Cantian metadata normalization.", nullptr, nullptr, -1, -1, 3, 0); -int32_t cluster_role = (int32_t)dis_cluster_role::DEFAULT; -static MYSQL_SYSVAR_INT(disaster_cluster_role, cluster_role, PLUGIN_VAR_READONLY, +int32_t ctc_cluster_role = (int32_t)dis_cluster_role::DEFAULT; +static MYSQL_SYSVAR_INT(cluster_role, ctc_cluster_role, PLUGIN_VAR_READONLY, "flag for Disaster Recovery Cluster Role.", nullptr, nullptr, -1, -1, 2, 0); int32_t ctc_max_cursors_no_autocommit = 128; @@ -229,7 +231,7 @@ static SYS_VAR *tse_system_variables[] = { MYSQL_SYSVAR(version), MYSQL_SYSVAR(stats_enabled), MYSQL_SYSVAR(autoinc_lock_mode), - MYSQL_SYSVAR(disaster_cluster_role), + MYSQL_SYSVAR(cluster_role), MYSQL_SYSVAR(update_analyze_time), nullptr }; @@ -3496,13 +3498,19 @@ EXTER_ATTACK int ha_tse::index_read(uchar *buf, const uchar *key, uint key_len, int len = strlen(table->key_info[active_index].name); memcpy(index_key_info.index_name, table->key_info[active_index].name, len + 1); - int ret = tse_fill_index_key_info(table, key, key_len, end_range, &index_key_info, m_is_reading_range); + index_key_info.index_skip_scan = false; + if (table->reginfo.qep_tab && table->reginfo.qep_tab->quick_optim() && + table->reginfo.qep_tab->quick_optim()->get_type() == QUICK_SELECT_I::QS_TYPE_SKIP_SCAN) { + index_key_info.index_skip_scan = true; + } + + int ret = tse_fill_index_key_info(table, key, key_len, end_range, &index_key_info, index_key_info.index_skip_scan); if (ret != CT_SUCCESS) { tse_log_error("ha_tse::index_read: fill index key info failed, ret(%d).", ret); return ret; } - bool has_right_key = m_is_reading_range && end_range != nullptr && end_range->length != 0; + bool has_right_key = !index_key_info.index_skip_scan && end_range != nullptr && end_range->length != 0; dec4_t d4[MAX_KEY_COLUMNS * 2]; ret = tse_convert_index_datatype(table, &index_key_info, has_right_key, d4); @@ -3519,12 +3527,6 @@ EXTER_ATTACK int ha_tse::index_read(uchar *buf, const uchar *key, uint key_len, update_member_tch(m_tch, tse_hton, ha_thd()); record_info_t record_info = {tse_buf, 0}; - index_key_info.index_skip_scan = false; - - if ((table->pos_in_table_list->opt_hints_qb) && - (hint_table_state(ha_thd(), table->pos_in_table_list, SKIP_SCAN_HINT_ENUM, OPTIMIZER_SKIP_SCAN))) { - index_key_info.index_skip_scan = true; - } attachable_trx_update_pre_addr(tse_hton, ha_thd(), &m_tch, true); ct_errno_t ct_ret = (ct_errno_t)tse_index_read(&m_tch, &record_info, &index_key_info, @@ -3551,21 +3553,6 @@ EXTER_ATTACK int ha_tse::index_read_last(uchar *buf, const uchar *key_ptr, uint return index_read(buf, key_ptr, key_len, HA_READ_PREFIX_LAST); } -int ha_tse::read_range_first(const key_range * start_key, const key_range * end_key, - bool eq_range_arg, bool sorted) { - m_is_reading_range = true; - int res = handler::read_range_first(start_key, end_key, eq_range_arg, sorted); - m_is_reading_range = false; - return res; -} - -int ha_tse::read_range_next() { - m_is_reading_range = true; - int res = handler::read_range_next(); - m_is_reading_range = false; - return res; -} - int ha_tse::index_fetch(uchar *buf) { DBUG_TRACE; int mysql_ret = 0; @@ -3980,22 +3967,22 @@ int ha_tse::records_from_index(ha_rows *num_rows, uint inx) } int32_t tse_get_cluster_role() { - if (cluster_role != (int32_t)dis_cluster_role::DEFAULT) { - return cluster_role; + if (ctc_cluster_role != (int32_t)dis_cluster_role::DEFAULT) { + return ctc_cluster_role; } - // todo: add mutex for cluster_role. + // todo: add mutex for ctc_cluster_role. bool is_slave = false; bool cantian_cluster_ready = false; int ret = tse_query_cluster_role(&is_slave, &cantian_cluster_ready); if (ret != CT_SUCCESS || !cantian_cluster_ready) { - cluster_role = (int32_t)dis_cluster_role::CLUSTER_NOT_READY; + ctc_cluster_role = (int32_t)dis_cluster_role::CLUSTER_NOT_READY; tse_log_error("[Disaster Rocovery] tse_query_cluster_role failed with error code: %d, is_slave:%d, cantian_cluster_ready: %d", ret, is_slave, cantian_cluster_ready); - return cluster_role; + return ctc_cluster_role; } tse_log_system("[Disaster Recovery] is_slave:%d, cantian_cluster_ready:%d", is_slave, cantian_cluster_ready); tse_set_cluster_role_by_cantian(is_slave); - return cluster_role; + return ctc_cluster_role; } /** @@ -4326,12 +4313,12 @@ void tse_reset_mysql_read_only() { } int tse_set_cluster_role_by_cantian(bool is_slave) { - // todo: add mutex for cluster_role + // todo: add mutex for ctc_cluster_role if (is_slave) { - cluster_role = (int32_t)dis_cluster_role::STANDBY; + ctc_cluster_role = (int32_t)dis_cluster_role::STANDBY; tse_set_mysql_read_only(); } else { - cluster_role = (int32_t)dis_cluster_role::PRIMARY; + ctc_cluster_role = (int32_t)dis_cluster_role::PRIMARY; tse_reset_mysql_read_only(); } return 0; @@ -4696,7 +4683,6 @@ static int tse_init_func(void *p) { tse_log_error("[CTC_INIT]:ctc_check_tx_isolation failed:%d", ret); return HA_ERR_INITIALIZATION; } - tse_log_system("[CTC_INIT]:SUCCESS!"); return 0; } diff --git a/storage/tianchi/ha_tse.h b/storage/tianchi/ha_tse.h index f4497b33bbdeb66b3ee472163fbc980fb239cfd2..eb4aa72fa918eccc7404af0436ae0ad61bc8cb92 100644 --- a/storage/tianchi/ha_tse.h +++ b/storage/tianchi/ha_tse.h @@ -498,11 +498,6 @@ public: int index_fetch(uchar *buf); - int read_range_first(const key_range *start_key, const key_range *end_key, - bool eq_range_arg, bool sorted) override; - - int read_range_next() override; - /** @brief Positions an index cursor to the index specified in the handle. Fetches the @@ -932,9 +927,6 @@ public: Item *m_pushed_conds = nullptr; Item *m_remainder_conds = nullptr; - /** Set to true if we are inside read_range_first() or read_range_next() **/ - bool m_is_reading_range = false; - private: int process_cantian_record(uchar *buf, record_info_t *record_info, ct_errno_t ct_ret, int rc_ret); int bulk_insert(); diff --git a/storage/tianchi/tse_cbo.cc b/storage/tianchi/tse_cbo.cc index 7bb639190d1f5bba673ddf266ed0983f1bc2e14e..e309fe7df7b6c45ece967ae49e9abc6265088f70 100644 --- a/storage/tianchi/tse_cbo.cc +++ b/storage/tianchi/tse_cbo.cc @@ -235,15 +235,40 @@ static double calc_hist_between_frequency(tse_cbo_stats_table_t cbo_stats, field } +double percent_in_bucket(cache_variant_t *max_val, cache_variant_t *val, cache_variant_t *min_val, enum_field_types field_type) +{ + if (compare(max_val, min_val, field_type) == EQUAL) { + return 1; + } + double percent = 0; + switch(field_type) { + case MYSQL_TYPE_TINY: + case MYSQL_TYPE_SHORT: + case MYSQL_TYPE_LONG: + percent = (double)(val->v_int - min_val->v_int) / (max_val->v_int - min_val->v_int); + break; + case MYSQL_TYPE_FLOAT: + case MYSQL_TYPE_DOUBLE: + percent = (double)(val->v_real - min_val->v_real) / (max_val->v_real - min_val->v_real); + break; + case MYSQL_TYPE_LONGLONG: + percent = (double)(val->v_bigint - min_val->v_bigint) / (max_val->v_bigint - min_val->v_bigint); + break; + default: + return DEFAULT_RANGE_DENSITY; + } + + return percent; +} + static int calc_hist_range_boundary(field_stats_val stats_val, enum_field_types field_type, tse_cbo_stats_column_t *col_stat, -double *percent) + double *percent, cache_variant_t *low_val) { en_tse_compare_type cmp_result; uint32 i, lo_pos, hi_pos; uint32 hist_count = col_stat->hist_count; tse_cbo_column_hist_t *hist_infos = col_stat->column_hist; - lo_pos = hi_pos = hist_count - 1; for (i = 0; i < hist_count; i++) { @@ -251,12 +276,10 @@ double *percent) if (cmp_result == GREAT) { lo_pos = i; + *percent -= percent_in_bucket(&hist_infos[i].ep_value, stats_val.min_key_val, low_val, field_type); break; } - } - - if (stats_val.min_type == CMP_TYPE_CLOSE_INTERNAL) { - *percent += calc_balance_hist_equal_density(col_stat, stats_val.min_key_val, field_type); + low_val = &hist_infos[i].ep_value; } for (i = lo_pos; i < hist_count; i++) { @@ -264,8 +287,18 @@ double *percent) if (cmp_result == GREAT || cmp_result == EQUAL) { hi_pos = i; + *percent += percent_in_bucket(&hist_infos[i].ep_value, stats_val.max_key_val, low_val, field_type); break; } + low_val = &hist_infos[i].ep_value; + } + + if (col_stat->num_buckets > 0) { + *percent = *percent / col_stat->num_buckets; + } + + if (stats_val.min_type == CMP_TYPE_CLOSE_INTERNAL) { + *percent += calc_balance_hist_equal_density(col_stat, stats_val.min_key_val, field_type); } if (stats_val.max_type == CMP_TYPE_CLOSE_INTERNAL) { @@ -285,7 +318,7 @@ static double calc_hist_between_balance(tse_cbo_stats_table_t cbo_stats, field_s } double percent = 0; - int bucket_range = calc_hist_range_boundary(stats_val, field_type, col_stat, &percent); + int bucket_range = calc_hist_range_boundary(stats_val, field_type, col_stat, &percent, &cbo_stats.columns[col_id].low_value); density = (double)bucket_range / col_stat->num_buckets + percent; return density; @@ -414,8 +447,8 @@ void tse_index_stats_update(TABLE *table, tianchi_cbo_stats_t *cbo_stats) if (is_part_table) { // set to the biggest part assert(cbo_stats->part_cnt); - for (uint32 part_id = 0; part_idpart_cnt; part_id++) { - if (estimate_rows < cbo_stats->tse_cbo_stats_part_table[part_id].estimate_rows) { + for (uint32 part_id = 0; part_id < cbo_stats->part_cnt; part_id++) { + if (estimate_rows <= cbo_stats->tse_cbo_stats_part_table[part_id].estimate_rows) { estimate_rows = cbo_stats->tse_cbo_stats_part_table[part_id].estimate_rows; n_diff = cbo_stats->tse_cbo_stats_part_table[part_id].ndv_keys; }