diff --git a/storage/ctc/ctc_srv.h b/storage/ctc/ctc_srv.h index 7a4de583f06237ca7c361be47e581644dd4b5a85..13f5de1189f5f9deac221e4f3876c137769da4ce 100644 --- a/storage/ctc/ctc_srv.h +++ b/storage/ctc/ctc_srv.h @@ -282,6 +282,8 @@ enum CTC_FUNC_TYPE { CTC_FUNC_TYPE_UPDATE_JOB, CTC_FUNC_TYPE_UPDATE_ROW, CTC_FUNC_TYPE_DELETE_ROW, + CTC_FUNC_TYPE_UPDATE_SAMPLE_SIZE, + CTC_FUNC_TYPE_GET_SAMPLE_SIZE, CTC_FUNC_TYPE_RND_INIT, CTC_FUNC_TYPE_RND_END, CTC_FUNC_TYPE_RND_NEXT, @@ -601,6 +603,8 @@ int ctc_truncate_partition(void *table_def, ddl_ctrl_t *ddl_ctrl); int ctc_rename_table(void *alter_def, ddl_ctrl_t *ddl_ctrl); int ctc_drop_table(void *drop_def, ddl_ctrl_t *ddl_ctrl); +int ctc_update_sample_size(uint32_t sample_size); +int ctc_get_sample_size(uint32_t *sample_size); int ctc_get_max_sessions_per_node(uint32_t *max_sessions); int ctc_get_serial_value(ctc_handler_t *tch, uint64_t *value, dml_flag_t flag); diff --git a/storage/ctc/ctc_srv_mq_stub.cc b/storage/ctc/ctc_srv_mq_stub.cc index 670c826de8119e1128004b60debc629c9d22430d..7c767ccce84e8b8163cb13f02da271b626a76f07 100644 --- a/storage/ctc/ctc_srv_mq_stub.cc +++ b/storage/ctc/ctc_srv_mq_stub.cc @@ -1636,6 +1636,47 @@ int ctc_query_cluster_role(bool *is_slave, bool *cantian_cluster_ready) { return result; } +int ctc_update_sample_size(uint32_t sample_size) +{ + void *shm_inst = get_one_shm_inst(nullptr); + + uint32_t *req = (uint32_t*)alloc_share_mem(shm_inst, sizeof(uint32_t)); + if (req == nullptr) { + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(uint32_t)); + return ERR_ALLOC_MEMORY; + } + *req = sample_size; + + int res = ctc_mq_deal_func(shm_inst, CTC_FUNC_TYPE_UPDATE_SAMPLE_SIZE, req, nullptr); + if (res != CT_SUCCESS) { + ctc_log_error("ctc_mq_deal_func CTC_FUNC_TYPE_UPDATE_SAMPLE_SIZE failed"); + } + free_share_mem(shm_inst, req); + + return res; +} + +int ctc_get_sample_size(uint32_t *sample_size) +{ + void *shm_inst = get_one_shm_inst(nullptr); + + uint32_t *req = (uint32_t*)alloc_share_mem(shm_inst, sizeof(uint32_t)); + if (req == nullptr) { + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(uint32_t)); + return ERR_ALLOC_MEMORY; + } + + int res = ctc_mq_deal_func(shm_inst, CTC_FUNC_TYPE_GET_SAMPLE_SIZE, req, nullptr); + if (res != CT_SUCCESS) { + ctc_log_error("ctc_mq_deal_func CTC_FUNC_TYPE_GET_SAMPLE_SIZE failed"); + } + *sample_size = *req; + ctc_log_error("[ctc_get_sample_size] size(%u)", *sample_size); + free_share_mem(shm_inst, req); + + return res; +} + int ctc_query_shm_file_num(uint32_t *shm_file_num) { void *shm_inst = get_one_shm_inst(NULL); @@ -1672,4 +1713,4 @@ int ctc_query_shm_usage(uint32_t *shm_usage) } free_share_mem(shm_inst, req); return result; -} +} \ No newline at end of file diff --git a/storage/ctc/ctc_stats.cc b/storage/ctc/ctc_stats.cc index a03a218bb16c8f8f388a243561bea203deada015..505bb529b99ba2c7ab89142c47e0cce724d9ca9f 100644 --- a/storage/ctc/ctc_stats.cc +++ b/storage/ctc/ctc_stats.cc @@ -26,6 +26,8 @@ const char *ctc_interface_strs[] = { "CTC_FUNC_TYPE_UPDATE_JOB", "CTC_FUNC_TYPE_UPDATE_ROW", "CTC_FUNC_TYPE_DELETE_ROW", + "CTC_FUNC_TYPE_UPDATE_SAMPLE_SIZE", + "CTC_FUNC_TYPE_GET_SAMPLE_SIZE", "CTC_FUNC_TYPE_RND_INIT", "CTC_FUNC_TYPE_RND_END", "CTC_FUNC_TYPE_RND_NEXT", @@ -223,4 +225,4 @@ void ctc_stats::print_stats(THD *thd, stat_print_fn *stat_print) { ctc_srv_monitor = &ctc_srv_monitor_str[0]; stat_print(thd, "ctc", static_cast(strlen("ctc")), STRING_WITH_LEN(""), ctc_srv_monitor, (uint)ctc_srv_monitor_str.length()); -} +} \ No newline at end of file diff --git a/storage/ctc/ha_ctc.cc b/storage/ctc/ha_ctc.cc index 6032249fe1662ecdff2860385382399a79d57d13..7b57d4030f1670a9217d1531077f2603a45f7b37 100644 --- a/storage/ctc/ha_ctc.cc +++ b/storage/ctc/ha_ctc.cc @@ -143,6 +143,10 @@ * mysql> SHOW GLOBAL VARIABLES like'%ctc%' */ +#define CTC_MAX_SAMPLE_SIZE (4096) // MB +#define CTC_MIN_SAMPLE_SIZE (32) // MB +#define CTC_DEFAULT_SAMPLE_SIZE (128) // MB + static void ctc_statistics_enabled_update(THD *, SYS_VAR *, void *var_ptr, const void *save) { bool val = *static_cast(var_ptr) = *static_cast(save); ctc_stats::get_instance().set_statistics_enabled(val); @@ -235,6 +239,41 @@ static MYSQL_SYSVAR_UINT(update_analyze_time, ctc_update_analyze_time, PLUGIN_VA "CBO updating time by CTC. Unit is second.", nullptr, nullptr, CTC_ANALYZE_TIME_SEC, 0, 900, 0); +static mutex m_ctc_sample_size_mutex; +uint32_t ctc_sample_size; +static int check_sample_size(THD *, SYS_VAR *, void *save, struct st_mysql_value *value) +{ + longlong in_val; + value->val_int(value, &in_val); + + if (in_val < CTC_MIN_SAMPLE_SIZE || in_val >= CTC_MAX_SAMPLE_SIZE) { + std::stringstream error_str; + error_str << "The value " << in_val + << " is not within the range of accepted values for the option " + << "ctc_sample_size.The value must be between " + << CTC_MIN_SAMPLE_SIZE << " inclusive and " + << CTC_MAX_SAMPLE_SIZE << " exclusive."; + my_message(ER_WRONG_VALUE_FOR_VAR, error_str.str().c_str(), MYF(0)); + + return CT_ERROR; + } + + *(longlong *)save = in_val; + + return CT_SUCCESS; +} +static void update_sample_size(THD *, SYS_VAR *, void *, const void *save) +{ + lock_guard lock(m_ctc_sample_size_mutex); + if (ctc_update_sample_size(*static_cast(save)) == CT_SUCCESS) { + ctc_sample_size = *static_cast(save); + } +} +static MYSQL_SYSVAR_UINT(sample_size, ctc_sample_size, PLUGIN_VAR_RQCMDARG, + "The size of the statistical sample data, measured in megabytes (MB).", + check_sample_size, update_sample_size, + CTC_DEFAULT_SAMPLE_SIZE, CTC_MIN_SAMPLE_SIZE, CTC_MAX_SAMPLE_SIZE, 0); + bool ctc_select_prefetch = true; static MYSQL_SYSVAR_BOOL(select_prefetch, ctc_select_prefetch, PLUGIN_VAR_RQCMDARG, "Indicates whether using prefetch in select.", nullptr, nullptr, true); @@ -243,6 +282,7 @@ static MYSQL_SYSVAR_BOOL(select_prefetch, ctc_select_prefetch, PLUGIN_VAR_RQCMDA // use. This is done by constructing a NULL-terminated array of the variables // and linking to it in the plugin public interface. static SYS_VAR *ctc_system_variables[] = { + MYSQL_SYSVAR(sample_size), MYSQL_SYSVAR(lock_wait_timeout), MYSQL_SYSVAR(instance_id), MYSQL_SYSVAR(sampling_ratio), @@ -4090,6 +4130,26 @@ int ha_ctc::records_from_index(ha_rows *num_rows, uint inx) return ret; } +/** + * Retrieves and validates the statistics sample size system variable from Cantian. + * + * This function: + * 1. Gets the sample size value from Cantian engine via ctc_get_sample_size() + * 2. Validates that the value falls within acceptable range [CTC_MIN_SAMPLE_SIZE, CTC_MAX_SAMPLE_SIZE] + * 3. If valid, updates the global ctc_sample_size variable used for statistics sampling + * + * The sample size determines how much data is sampled when gathering table statistics. + * Invalid values are silently ignored, leaving ctc_sample_size unchanged. + */ +void ctc_get_sys_var() { + uint32_t sample_size = 0; + if (ctc_get_sample_size(&sample_size) == CT_SUCCESS) { + if (sample_size >= CTC_MIN_SAMPLE_SIZE && sample_size <= CTC_MAX_SAMPLE_SIZE) { + ctc_sample_size = sample_size; + } + } +} + int32_t ctc_get_cluster_role() { if (ctc_cluster_role != (int32_t)dis_cluster_role::DEFAULT) { return ctc_cluster_role; @@ -4838,6 +4898,9 @@ static int ctc_init_func(void *p) { return HA_ERR_INITIALIZATION; } ctc_get_cluster_role(); + + ctc_get_sys_var(); + ctc_log_system("[CTC_INIT]:SUCCESS!"); return 0; }