From 15ec94d1ad1abc480597b78f8990a2bbfc9c9a26 Mon Sep 17 00:00:00 2001 From: pengbingjie Date: Sun, 26 Jan 2025 22:55:43 +0800 Subject: [PATCH] proxy_user --- mysql-test/mysql-source-code-meta.patch | 57 ++++++-- storage/ctc/ctc_ddl_rewriter_plugin.cc | 131 +---------------- storage/ctc/ha_ctc.cc | 185 ++++++++++++++++++++++++ 3 files changed, 232 insertions(+), 141 deletions(-) diff --git a/mysql-test/mysql-source-code-meta.patch b/mysql-test/mysql-source-code-meta.patch index 26bab31..5794762 100644 --- a/mysql-test/mysql-source-code-meta.patch +++ b/mysql-test/mysql-source-code-meta.patch @@ -986,7 +986,7 @@ index 217a0c19..5e93df0f 100644 if (unlikely(error)) return error; diff --git a/sql/handler.h b/sql/handler.h -index 0530ca15..bab9b083 100644 +index 0530ca15..efeaf90e 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -662,7 +662,8 @@ enum legacy_db_type { @@ -999,7 +999,19 @@ index 0530ca15..bab9b083 100644 DB_TYPE_DEFAULT = 127 // Must be last }; -@@ -1334,7 +1335,7 @@ typedef xa_status_code (*rollback_by_xid_t)(handlerton *hton, XID *xid); +@@ -1242,6 +1243,11 @@ typedef int (*savepoint_rollback_t)(handlerton *hton, THD *thd, void *sv); + */ + typedef int (*savepoint_set_t)(handlerton *hton, THD *thd, void *sv); + ++/** ++ Broadcast global system variables when metadata is normalized. ++*/ ++typedef int (*update_sysvars_t)(handlerton *hton, THD *thd); ++ + /** + Check if storage engine allows to release metadata locks which were + acquired after the savepoint if rollback to savepoint is done. +@@ -1334,7 +1340,7 @@ typedef xa_status_code (*rollback_by_xid_t)(handlerton *hton, XID *xid); typedef handler *(*create_t)(handlerton *hton, TABLE_SHARE *table, bool partitioned, MEM_ROOT *mem_root); @@ -1008,7 +1020,7 @@ index 0530ca15..bab9b083 100644 typedef int (*panic_t)(handlerton *hton, enum ha_panic_function flag); -@@ -1510,7 +1511,7 @@ typedef int (*fill_is_table_t)(handlerton *hton, THD *thd, TABLE_LIST *tables, +@@ -1510,7 +1516,7 @@ typedef int (*fill_is_table_t)(handlerton *hton, THD *thd, TABLE_LIST *tables, typedef int (*binlog_func_t)(handlerton *hton, THD *thd, enum_binlog_func fn, void *arg); @@ -1017,7 +1029,7 @@ index 0530ca15..bab9b083 100644 enum_binlog_command binlog_command, const char *query, uint query_length, const char *db, const char *table_name); -@@ -2133,6 +2134,14 @@ typedef bool (*check_fk_column_compat_t)( +@@ -2133,6 +2139,14 @@ typedef bool (*check_fk_column_compat_t)( typedef bool (*is_reserved_db_name_t)(handlerton *hton, const char *name); @@ -1032,7 +1044,7 @@ index 0530ca15..bab9b083 100644 /** Prepare the secondary engine for executing a statement. This function is called right after the secondary engine TABLE objects have been opened by -@@ -2420,6 +2429,8 @@ struct handlerton { +@@ -2420,6 +2434,8 @@ struct handlerton { */ uint savepoint_offset; @@ -1041,10 +1053,12 @@ index 0530ca15..bab9b083 100644 /* handlerton methods */ close_connection_t close_connection; -@@ -2464,6 +2475,15 @@ struct handlerton { +@@ -2463,6 +2479,16 @@ struct handlerton { + dict_get_server_version_t dict_get_server_version; dict_set_server_version_t dict_set_server_version; is_reserved_db_name_t is_reserved_db_name; - ++ update_sysvars_t update_sysvars; ++ + /** CTC metadata methods. */ + get_inst_id_t get_inst_id; + set_metadata_switch_t set_metadata_switch; @@ -1053,11 +1067,10 @@ index 0530ca15..bab9b083 100644 + op_before_load_meta_t op_before_load_meta; + op_after_load_meta_t op_after_load_meta; + get_cluster_role_t get_cluster_role; -+ + /** Global handler flags. */ uint32 flags{0}; - -@@ -4482,7 +4502,7 @@ class handler { +@@ -4482,7 +4508,7 @@ class handler { and delete_row() below. */ int ha_external_lock(THD *thd, int lock_type); @@ -1066,7 +1079,7 @@ index 0530ca15..bab9b083 100644 /** Update the current row. -@@ -6161,12 +6181,13 @@ class handler { +@@ -6161,12 +6187,13 @@ class handler { } @param buf Buffer to write from. @@ -1081,7 +1094,7 @@ index 0530ca15..bab9b083 100644 return HA_ERR_WRONG_COMMAND; } -@@ -6178,6 +6199,7 @@ class handler { +@@ -6178,6 +6205,7 @@ class handler { the columns required for the error message are not read, the error message will contain garbage. */ @@ -1089,7 +1102,7 @@ index 0530ca15..bab9b083 100644 virtual int update_row(const uchar *old_data MY_ATTRIBUTE((unused)), uchar *new_data MY_ATTRIBUTE((unused))) { return HA_ERR_WRONG_COMMAND; -@@ -6874,7 +6896,7 @@ void ha_pre_dd_shutdown(void); +@@ -6874,7 +6902,7 @@ void ha_pre_dd_shutdown(void); @retval true Error */ bool ha_flush_logs(bool binlog_group_flush = false); @@ -1098,7 +1111,7 @@ index 0530ca15..bab9b083 100644 int ha_create_table(THD *thd, const char *path, const char *db, const char *table_name, HA_CREATE_INFO *create_info, bool update_create_info, bool is_temp_table, -@@ -6973,7 +6995,7 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht, +@@ -6973,7 +7001,7 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht, int ha_reset_logs(THD *thd); int ha_binlog_index_purge_file(THD *thd, const char *file); void ha_reset_slave(THD *thd); @@ -1669,6 +1682,18 @@ index e16b39c4..efdfba2c 100644 THD_STAGE_INFO(thd, stage_compressing_gtid_table); /* Compressing the gtid_executed table. */ if (gtid_state->compress(thd)) { +diff --git a/sql/set_var.cc b/sql/set_var.cc +index 4523e2c0..ef9fb32d 100644 +--- a/sql/set_var.cc ++++ b/sql/set_var.cc +@@ -855,6 +855,7 @@ int sql_set_variables(THD *thd, List *var_list, bool opened) { + } + if ((error = thd->is_error())) goto err; + ++ if ((error = ctc_hton->update_sysvars(ctc_hton, thd))) goto err; + it.rewind(); + while ((var = it++)) { + if ((error = var->update(thd))) // Returns 0, -1 or 1 diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c171f0bb..6fc75f7c 100644 --- a/sql/sql_class.cc @@ -3860,13 +3885,13 @@ index e949235a..d46fca83 100644 opened_table_validate(); diff --git a/cmake/info_macros.cmake.in b/cmake/info_macros.cmake.in -index 19110c7..131a4c6 100644 +index 19110c7a..131a4c69 100644 --- a/cmake/info_macros.cmake.in +++ b/cmake/info_macros.cmake.in @@ -106,6 +106,7 @@ MACRO(CREATE_INFO_SRC target_dir) ELSE() # This is a fall-back. FILE(WRITE ${INFO_SRC} "\nMySQL source ${VERSION}\n") -+ FILE(APPEND ${INFO_SRC} "\nCantian patch source 1.0.0\n") ++ FILE(APPEND ${INFO_SRC} "\nCantian patch source 1.0.1\n") ENDIF() ENDMACRO(CREATE_INFO_SRC) \ No newline at end of file diff --git a/storage/ctc/ctc_ddl_rewriter_plugin.cc b/storage/ctc/ctc_ddl_rewriter_plugin.cc index 661505f..45fc29a 100644 --- a/storage/ctc/ctc_ddl_rewriter_plugin.cc +++ b/storage/ctc/ctc_ddl_rewriter_plugin.cc @@ -451,69 +451,8 @@ static int ctc_check_flush(string &, MYSQL_THD thd, bool &need_forward) { return 0; } -static uint32_t ctc_set_var_option(bool is_null_value, bool is_set_default_value, - enum_var_type type) { - uint32_t options = 0; - if (is_null_value) { - options |= CTC_SET_VARIABLE_TO_NULL; - } - if (is_set_default_value) { - options |= CTC_SET_VARIABLE_TO_DEFAULT; - } - if (type == OPT_PERSIST_ONLY) { - options |= CTC_SET_VARIABLE_PERSIST_ONLY; - } - if (type == OPT_PERSIST) { - options |= CTC_SET_VARIABLE_PERSIST; - } - return options; -} - -static int ctc_set_var_meta(MYSQL_THD thd, list variables_info, ctc_set_opt_request *set_opt_request) { - ctc_handler_t tch; - tch.inst_id = ctc_instance_id; - handlerton* hton = get_ctc_hton(); - - CTC_RETURN_IF_NOT_ZERO(get_tch_in_handler_data(hton, thd, tch)); - - set_opt_request->mysql_inst_id = ctc_instance_id; - set_opt_request->opt_num = variables_info.size(); - set_opt_request->err_code = 0; - memset(set_opt_request->err_msg, 0, ERROR_MESSAGE_LEN); - set_opt_request->set_opt_info = (set_opt_info_t *)my_malloc(PSI_NOT_INSTRUMENTED, - variables_info.size() * sizeof(set_opt_info_t), - MYF(MY_WME)); - if (set_opt_request->set_opt_info == nullptr) { - ctc_log_error("alloc mem failed, set_opt_info size(%lu)", variables_info.size() * sizeof(set_opt_info_t)); - return HA_ERR_OUT_OF_MEM; - } - memset(set_opt_request->set_opt_info, 0, variables_info.size() * sizeof(set_opt_info_t)); - set_opt_info_t *set_opt_info_begin = set_opt_request->set_opt_info; - for (auto it = variables_info.begin(); it != variables_info.end(); ++it) { - auto var_info = *it; - strncpy(set_opt_info_begin->var_name, var_info.var_name, SMALL_RECORD_SIZE - 1); - strncpy(set_opt_info_begin->var_value, var_info.var_value, MAX_DDL_SQL_LEN - 1); - set_opt_info_begin->options |= CTC_NOT_NEED_CANTIAN_EXECUTE; - set_opt_info_begin->options |= (thd->lex->contains_plaintext_password ? - CTC_CURRENT_SQL_CONTAIN_PLAINTEXT_PASSWORD : 0); - set_opt_info_begin->options |= var_info.options; - if (var_info.var_is_int) { - // actual value of the variable type int - set_opt_info_begin->var_is_int = true; - } - memset(set_opt_info_begin->base_name, 0, SMALL_RECORD_SIZE); - strncpy(set_opt_info_begin->base_name, var_info.base_name, SMALL_RECORD_SIZE - 1); - set_opt_info_begin += 1; - } - int ret = ctc_execute_set_opt(&tch, set_opt_request, true); - update_sess_ctx_by_tch(tch, hton, thd); - my_free(set_opt_request->set_opt_info); - set_opt_request->set_opt_info = nullptr; - return ret; -} - static int ctc_get_variables_value_string(MYSQL_THD thd, string &sql_str, set_var* setvar, string& val_str, - bool& is_null_value, bool &need_forward) { + bool &need_forward) { Item_func_get_user_var *itemFunc = dynamic_cast(setvar->value); Item_func_get_system_var *itemFuncSys = dynamic_cast(setvar->value); @@ -545,7 +484,6 @@ static int ctc_get_variables_value_string(MYSQL_THD thd, string &sql_str, set_va itemFuncSys->fixed = true; new_str = itemFuncSys->val_str(&str); if (!new_str) { - is_null_value = true; val_str = "null"; } else if (new_str == itemFuncSys->error_str()) { need_forward = false; @@ -558,7 +496,6 @@ static int ctc_get_variables_value_string(MYSQL_THD thd, string &sql_str, set_va String* new_str; String str; if (!(new_str = setvar->value->val_str(&str))) { - is_null_value = true; val_str = "null"; } else { val_str = new_str->c_ptr(); @@ -605,17 +542,6 @@ static int ctc_set_user_var_flag(MYSQL_THD thd, string name, string value) { return 0; } -static void ctc_set_var_info(set_var_info *var_info, const char *base_name, string name, - string value, uint32_t options, bool var_is_int) { - if (base_name != nullptr) { - strncpy(var_info->base_name, base_name, SMALL_RECORD_SIZE - 1); - } - strncpy(var_info->var_name, name.c_str(), SMALL_RECORD_SIZE - 1); - strncpy(var_info->var_value, value.c_str(), MAX_DDL_SQL_LEN - 1); - var_info->options = options; - var_info->var_is_int = var_is_int; -} - static int check_non_system_var(set_var_base *var, bool& need_forward, MYSQL_THD thd) { need_forward = false; if (typeid(*var) != typeid(set_var_user)) { @@ -655,16 +581,11 @@ static int check_non_system_var(set_var_base *var, bool& need_forward, MYSQL_THD } static int check_system_var(set_var_base *var, string &sql_str, MYSQL_THD thd, - bool &need_forward, bool &contain_subselect, - list &variables_info) { + bool &need_forward, bool &contain_subselect) { set_var *setvar = dynamic_cast(var); - bool is_set_default_value = false; - bool is_null_value = false; int ret = 0; string name_str; string val_str; - set_var_info var_info; - memset(&var_info, 0, sizeof(var_info)); #ifdef FEATURE_X_FOR_MYSQL_32 if (setvar) { std::function f = [&thd, &need_forward, setvar] @@ -684,11 +605,8 @@ static int check_system_var(set_var_base *var, string &sql_str, MYSQL_THD thd, #endif if (!contain_subselect) { /* get user value (@xxxxx) as string */ - if (!setvar->value) { - is_set_default_value = true; - val_str = ""; - } else { - ret = ctc_get_variables_value_string(thd, sql_str, setvar, val_str, is_null_value, need_forward); + if (setvar->value) { + ret = ctc_get_variables_value_string(thd, sql_str, setvar, val_str, need_forward); } ret |= ctc_check_set_opt_rule(setvar, name_str, val_str, need_forward); } @@ -705,30 +623,9 @@ static int check_system_var(set_var_base *var, string &sql_str, MYSQL_THD thd, ctc_log_error("Set global variable query is not allowed (ctc_setopt_disabled = true)"); return -1; } - - if (IS_METADATA_NORMALIZATION() && !contain_subselect && need_forward && setvar) { - if (setvar->check(thd) == 0) { - bool var_is_int = false; - if (setvar->value && setvar->value->result_type() == INT_RESULT) { - var_is_int = true; - } - uint32_t options = ctc_set_var_option(is_null_value, is_set_default_value, setvar->type); -#ifdef FEATURE_X_FOR_MYSQL_26 - const char *base_name = setvar->base.str; -#elif defined(FEATURE_X_FOR_MYSQL_32) - const char *base_name = setvar->m_var_tracker.get_var_name(); -#endif - ctc_set_var_info(&var_info, base_name, name_str, val_str, options, var_is_int); - variables_info.emplace_back(var_info); - } else { - thd->clear_error(); - need_forward = false; // 值校验失败, ctc不进行广播并返回成功, 后续报错由MySQL完成 - } - } return ret; } -/* 参考set_var.cc: sql_set_variables */ static int ctc_check_set_opt(string &sql_str, MYSQL_THD thd, bool &need_forward) { List_iterator_fast var_it(thd->lex->var_list); @@ -741,7 +638,6 @@ static int ctc_check_set_opt(string &sql_str, MYSQL_THD thd, bool &need_forward) contain_subselect = true; } var_it.rewind(); - list variables_info; while ((var = var_it++)) { if (typeid(*var) != typeid(set_var)) { ret = check_non_system_var(var, need_forward, thd); @@ -750,7 +646,7 @@ static int ctc_check_set_opt(string &sql_str, MYSQL_THD thd, bool &need_forward) return -1; } } else { - ret = check_system_var(var, sql_str, thd, need_forward, contain_subselect, variables_info); + ret = check_system_var(var, sql_str, thd, need_forward, contain_subselect); if (ret != 0) { ctc_log_error("check system var failed, set option %s", sql_str.c_str()); return -1; @@ -758,22 +654,7 @@ static int ctc_check_set_opt(string &sql_str, MYSQL_THD thd, bool &need_forward) } ctc_log_debug("set option %s, need_forward: %d", sql_str.c_str(), need_forward); } - if (!variables_info.empty()) { - if (variables_info.size() > CTC_MAX_SET_VAR_NUM) { - my_printf_error(ER_DISALLOWED_OPERATION, "Only %d variables can be set at a time", MYF(0), CTC_MAX_SET_VAR_NUM); - ctc_log_error("Only %d variables can be set at a time", CTC_MAX_SET_VAR_NUM); - return -1; - } - ctc_set_opt_request set_opt_request; - ret = ctc_set_var_meta(thd, variables_info, &set_opt_request); - if (ret != 0 && set_opt_request.err_code != 0) { - string err_msg = set_opt_request.err_msg; - my_printf_error(set_opt_request.err_code, "%s", MYF(0), err_msg.c_str()); - ctc_log_error("%s", err_msg.c_str()); - return ret; - } - } - if (IS_METADATA_NORMALIZATION() && !contain_subselect) { + if (IS_METADATA_NORMALIZATION()) { need_forward = false; } return ret; diff --git a/storage/ctc/ha_ctc.cc b/storage/ctc/ha_ctc.cc index b10ef70..178c2ae 100644 --- a/storage/ctc/ha_ctc.cc +++ b/storage/ctc/ha_ctc.cc @@ -2030,6 +2030,190 @@ static int ctc_release_savepoint(handlerton *hton, THD *thd, void *savepoint) { return convert_ctc_error_code_to_mysql(ret); } +static int ctc_set_var_meta(MYSQL_THD thd, list variables_info, ctc_set_opt_request *set_opt_request) { + ctc_handler_t tch; + tch.inst_id = ctc_instance_id; + handlerton* hton = get_ctc_hton(); + + CTC_RETURN_IF_NOT_ZERO(get_tch_in_handler_data(hton, thd, tch)); + + set_opt_request->mysql_inst_id = ctc_instance_id; + set_opt_request->opt_num = variables_info.size(); + set_opt_request->err_code = 0; + memset(set_opt_request->err_msg, 0, ERROR_MESSAGE_LEN); + set_opt_request->set_opt_info = (set_opt_info_t *)my_malloc(PSI_NOT_INSTRUMENTED, + variables_info.size() * sizeof(set_opt_info_t), + MYF(MY_WME)); + if (set_opt_request->set_opt_info == nullptr) { + ctc_log_error("alloc mem failed, set_opt_info size(%lu)", variables_info.size() * sizeof(set_opt_info_t)); + return HA_ERR_OUT_OF_MEM; + } + memset(set_opt_request->set_opt_info, 0, variables_info.size() * sizeof(set_opt_info_t)); + set_opt_info_t *set_opt_info_begin = set_opt_request->set_opt_info; + for (auto it = variables_info.begin(); it != variables_info.end(); ++it) { + auto var_info = *it; + strncpy(set_opt_info_begin->var_name, var_info.var_name, SMALL_RECORD_SIZE - 1); + strncpy(set_opt_info_begin->var_value, var_info.var_value, MAX_DDL_SQL_LEN - 1); + set_opt_info_begin->options |= CTC_NOT_NEED_CANTIAN_EXECUTE; + set_opt_info_begin->options |= (thd->lex->contains_plaintext_password ? + CTC_CURRENT_SQL_CONTAIN_PLAINTEXT_PASSWORD : 0); + set_opt_info_begin->options |= var_info.options; + if (var_info.var_is_int) { + // actual value of the variable type int + set_opt_info_begin->var_is_int = true; + } + memset(set_opt_info_begin->base_name, 0, SMALL_RECORD_SIZE); + strncpy(set_opt_info_begin->base_name, var_info.base_name, SMALL_RECORD_SIZE - 1); + set_opt_info_begin += 1; + } + int ret = ctc_execute_set_opt(&tch, set_opt_request, true); + update_sess_ctx_by_tch(tch, hton, thd); + my_free(set_opt_request->set_opt_info); + set_opt_request->set_opt_info = nullptr; + return ret; +} + +static void ctc_set_var_info(set_var_info *var_info, const char *base_name, string name, + string value, uint32_t options, bool var_is_int) { + if (base_name != nullptr) { + strncpy(var_info->base_name, base_name, SMALL_RECORD_SIZE - 1); + } + strncpy(var_info->var_name, name.c_str(), SMALL_RECORD_SIZE - 1); + strncpy(var_info->var_value, value.c_str(), MAX_DDL_SQL_LEN - 1); + var_info->options = options; + var_info->var_is_int = var_is_int; +} + +static uint32_t ctc_set_var_option(bool is_null_value, bool is_set_default_value, + enum_var_type type) { + uint32_t options = 0; + if (is_null_value) { + options |= CTC_SET_VARIABLE_TO_NULL; + } + if (is_set_default_value) { + options |= CTC_SET_VARIABLE_TO_DEFAULT; + } + if (type == OPT_PERSIST_ONLY) { + options |= CTC_SET_VARIABLE_PERSIST_ONLY; + } + if (type == OPT_PERSIST) { + options |= CTC_SET_VARIABLE_PERSIST; + } + return options; +} + +static int ctc_get_sysvar_value_string(set_var *var, string &name_str, string &val_str, + bool &is_null_value, bool &is_default_value) { + if (!var->value) { + is_default_value = true; + val_str = ""; + } else { + String str; + String* new_str = var->value->val_str(&str); + if (!new_str) { + is_null_value = true; + val_str = "null"; + } else { + val_str = new_str->c_ptr(); + } + } + if (strlen(val_str.c_str()) > MAX_DDL_SQL_LEN) { + my_printf_error(ER_DISALLOWED_OPERATION, "Set the variable '%s' failed: value is too long", + MYF(0), name_str.c_str()); + ctc_log_error("Set the variable '%s' failed: value is too long", name_str.c_str()); + return -1; + } + return 0; +} + +static int ctc_emplace_sysvars(set_var_base *var, THD *thd, list &variables_info) { + UNUSED_PARAM(thd); + int ret = 0; + set_var *setvar = dynamic_cast(var); + set_var_info var_info; + memset(&var_info, 0, sizeof(var_info)); + string name_str; + string val_str; + bool is_null_value = false; + bool is_set_default_value = false; + bool need_forward = false; + if (setvar) { +#ifdef FEATURE_X_FOR_MYSQL_26 + if (setvar->var) { + need_forward = !setvar->var->is_readonly() && setvar->is_global_persist() && + setvar->var->check_scope(OPT_GLOBAL); + } + const char *base_name = setvar->base.str; + name_str = setvar->var->name.str; +#elif defined(FEATURE_X_FOR_MYSQL_32) + std::function f = [&thd, &need_forward, setvar] + (const System_variable_tracker &, sys_var *system_var) { + if (system_var) { + need_forward = !system_var->is_readonly() && setvar->is_global_persist(); + } + return true; + }; + const char *base_name = setvar->m_var_tracker.get_var_name(); + name_str = setvar->m_var_tracker.get_var_name(); +#endif + if (IS_METADATA_NORMALIZATION() && need_forward) { + bool var_is_int = false; + if (setvar->value && setvar->value->result_type() == INT_RESULT) { + var_is_int = true; + } + if (ctc_get_sysvar_value_string(setvar, name_str, val_str, is_null_value, is_set_default_value)) { + return -1; + } + uint32_t options = ctc_set_var_option(is_null_value, is_set_default_value, setvar->type); + ctc_set_var_info(&var_info, base_name, name_str, val_str, options, var_is_int); + variables_info.emplace_back(var_info); + } + } + return ret; +} + +/** + Broadcast system variables when metadata is normalized. +*/ +static int ctc_update_sysvars(handlerton *hton, THD *thd) { + UNUSED_PARAM(hton); + if (is_ctc_mdl_thd(thd)) { + return 0; + } + List_iterator_fast var_it(thd->lex->var_list); + set_var_base *var = nullptr; + int ret = 0; + + var_it.rewind(); + list variables_info; + while ((var = var_it++)) { + if (typeid(*var) == typeid(set_var)) { + if (ctc_emplace_sysvars(var, thd, variables_info)) { + return -1; + } + } + } + if (!variables_info.empty()) { + if (variables_info.size() > CTC_MAX_SET_VAR_NUM) { + my_printf_error(ER_DISALLOWED_OPERATION, "There are currently %lu variables that need to be set," + "but only %d variables can be set at a time. ", MYF(0), + variables_info.size(), CTC_MAX_SET_VAR_NUM); + ctc_log_error("There are currently %lu variables that need to be set," + "but only %d variables can be set at a time. ", variables_info.size(), CTC_MAX_SET_VAR_NUM); + return -1; + } + ctc_set_opt_request set_opt_request; + ret = ctc_set_var_meta(thd, variables_info, &set_opt_request); + if (ret != 0 && set_opt_request.err_code != 0) { + string err_msg = set_opt_request.err_msg; + my_printf_error(set_opt_request.err_code, "%s", MYF(0), err_msg.c_str()); + ctc_log_error("Error code %d, %s", set_opt_request.err_code, err_msg.c_str()); + return ret; + } + } + return ret; +} + /** fill prefetch buffer by calling batch-read intfs @param: buf out, return one record in mysql format in order to reduce memcpy @@ -4679,6 +4863,7 @@ static typename std::enable_if::type set_hton_ ctc_hton->drop_database = ctc_drop_database_with_err; ctc_hton->binlog_log_query = ctc_binlog_log_query_with_err; ctc_hton->get_cluster_role = ctc_get_cluster_role; + ctc_hton->update_sysvars = ctc_update_sysvars; } template -- Gitee