diff --git a/include/mysql/components/services/clone_protocol_service.h b/include/mysql/components/services/clone_protocol_service.h index 827f8f66fdf..29b60013272 100644 --- a/include/mysql/components/services/clone_protocol_service.h +++ b/include/mysql/components/services/clone_protocol_service.h @@ -59,9 +59,11 @@ struct mysql_clone_ssl_context { const char *m_ssl_cert; /** Clone ssl certificate authority. Same as mysql client --ssl-ca */ const char *m_ssl_ca; - - /** Enable network compression. */ + /** Enable legacy network compression. */ bool m_enable_compression; + /** Network compression. */ + const char *m_compression_algorithms; + uint m_zstd_compression_level; NET_SERVER *m_server_extn; }; diff --git a/plugin/clone/include/clone.h b/plugin/clone/include/clone.h index c39746d197c..23fb71be9c1 100644 --- a/plugin/clone/include/clone.h +++ b/plugin/clone/include/clone.h @@ -88,9 +88,15 @@ extern uint clone_max_network_bandwidth; /** Clone system variable: Maximum IO bandwidth in MiB/sec */ extern uint clone_max_io_bandwidth; -/** Clone system variable: If network compression is enabled */ +/** Clone system variable: If legacy network compression is enabled */ extern bool clone_enable_compression; +/** Clone system variable: If network compression is enabled */ +extern char *clone_compression_algorithms; + +/** Clone system variable: If network compression with zstd is enabled */ +extern uint clone_zstd_compression_level; + /** Clone system variable: SSL private key */ extern char *clone_client_ssl_private_key; diff --git a/plugin/clone/src/clone_client.cc b/plugin/clone/src/clone_client.cc index 021a3c9478c..eaaddc55783 100644 --- a/plugin/clone/src/clone_client.cc +++ b/plugin/clone/src/clone_client.cc @@ -891,8 +891,9 @@ int Client::connect_remote(bool is_restart, bool use_aux) { mysql_clone_ssl_context ssl_context; ssl_context.m_enable_compression = clone_enable_compression; - ssl_context.m_server_extn = - ssl_context.m_enable_compression ? &m_conn_server_extn : nullptr; + ssl_context.m_compression_algorithms = clone_compression_algorithms; + ssl_context.m_zstd_compression_level = clone_zstd_compression_level; + ssl_context.m_server_extn = &m_conn_server_extn; ssl_context.m_ssl_mode = m_share->m_ssl_mode; /* Get Clone SSL configuration parameter value safely. */ diff --git a/plugin/clone/src/clone_plugin.cc b/plugin/clone/src/clone_plugin.cc index 6b230c24e54..a12e7d7246d 100644 --- a/plugin/clone/src/clone_plugin.cc +++ b/plugin/clone/src/clone_plugin.cc @@ -68,6 +68,12 @@ uint clone_max_io_bandwidth; /** Clone system variable: If network compression is enabled */ bool clone_enable_compression; +/** Clone system variable: If network compression is enabled */ +char *clone_compression_algorithms; + +/** Clone system variable: If network compression with zstd is enabled */ +uint clone_zstd_compression_level; + /** Clone system variable: valid list of donor addresses. */ static char *clone_valid_donor_list; @@ -332,6 +338,66 @@ static int check_donor_addr_format(MYSQL_THD thd, SYS_VAR *var [[maybe_unused]], return (0); } +/** Check clone compression algorithm +@param[in] thd user session THD +@param[in] var system variable +@param[out] save possibly updated variable value +@param[in] value current variable value +@return error code + */ +static int check_compression_algorithms(MYSQL_THD thd, + SYS_VAR *var [[maybe_unused]], + void *save, + struct st_mysql_value *value) { + char temp_buffer[STRING_BUFFER_USUAL_SIZE]; + auto buf_len = static_cast(sizeof(temp_buffer)); + + auto compression_algorithms = value->val_str(value, temp_buffer, &buf_len); + + if (compression_algorithms && (compression_algorithms == temp_buffer)) { + compression_algorithms = thd_strmake(thd, compression_algorithms, buf_len); + } + + if (compression_algorithms == nullptr) return 1; + + std::string compress_option(static_cast(compression_algorithms)); + std::vector list; + parse_compression_algorithms_list(compress_option, list); + auto it = list.begin(); + while (it != list.end()) { + std::string value = *it; + switch (get_compression_algorithm(value)) { + case enum_compression_algorithm::MYSQL_INVALID: + return 1; + default: + break; + } + it++; + } + *(const char **)save = compression_algorithms; + return 0; +} + +/** Check clone zstd compression level +@param[in] thd user session THD +@param[in] var system variable +@param[out] save possibly updated variable value +@param[in] value current variable value +@return error code + */ +static int check_zstd_compression_level(MYSQL_THD thd [[maybe_unused]], + SYS_VAR *var [[maybe_unused]], + void *save [[maybe_unused]], + struct st_mysql_value *value) { + long long new_value; + if (value->val_int(value, &new_value)) return 1; /* NULL value */ + if (is_zstd_compression_level_valid(static_cast(new_value))) { + *((uint *)save) = new_value; + return 0; + } + return 1; +} + /** Check if it is safe to uninstall plugin. @param[in] plugin_info server plugin handle @return error code */ @@ -576,6 +642,21 @@ static MYSQL_SYSVAR_BOOL(enable_compression, clone_enable_compression, "If compression is done at network", nullptr, nullptr, false); /* Disable compression by default */ +static MYSQL_SYSVAR_STR(compression_algorithms, clone_compression_algorithms, + PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_MEMALLOC, + "If compression is done at network", check_compression_algorithms, nullptr, + COMPRESSION_ALGORITHM_UNCOMPRESSED); /* Default = "uncompressed" */ + +/** If data is compressed in network layer by zstd */ +static MYSQL_SYSVAR_UINT(zstd_compression_level, + clone_zstd_compression_level, PLUGIN_VAR_OPCMDARG, + "If compression is done at network and use zstd compression", + check_zstd_compression_level, nullptr, + default_zstd_compression_level, /* Default */ + 1, /* Minimum */ + 22, /* Maximum */ + 1); /* Step */ + /** List of valid donor addresses allowed to clone from. */ static MYSQL_SYSVAR_STR(valid_donor_list, clone_valid_donor_list, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_MEMALLOC, @@ -638,6 +719,8 @@ static SYS_VAR *clone_system_variables[] = { MYSQL_SYSVAR(max_network_bandwidth), MYSQL_SYSVAR(max_data_bandwidth), MYSQL_SYSVAR(enable_compression), + MYSQL_SYSVAR(compression_algorithms), + MYSQL_SYSVAR(zstd_compression_level), MYSQL_SYSVAR(autotune_concurrency), MYSQL_SYSVAR(valid_donor_list), MYSQL_SYSVAR(ssl_key), diff --git a/sql/server_component/clone_protocol_service.cc b/sql/server_component/clone_protocol_service.cc index f813e84206a..fe84230e084 100644 --- a/sql/server_component/clone_protocol_service.cc +++ b/sql/server_component/clone_protocol_service.cc @@ -491,11 +491,13 @@ DEFINE_METHOD(MYSQL *, mysql_clone_connect, mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, reinterpret_cast(&timeout)); - /* Enable compression. */ if (ssl_ctx->m_enable_compression) { mysql_options(mysql, MYSQL_OPT_COMPRESS, nullptr); - mysql_extension_set_server_extn(mysql, ssl_ctx->m_server_extn); + } else { + mysql_options(mysql, MYSQL_OPT_COMPRESSION_ALGORITHMS, ssl_ctx->m_compression_algorithms); + mysql_options(mysql, MYSQL_OPT_ZSTD_COMPRESSION_LEVEL, &ssl_ctx->m_zstd_compression_level); } + mysql_extension_set_server_extn(mysql, ssl_ctx->m_server_extn); ret_mysql = mysql_real_connect(mysql, host, user, passwd, nullptr, port, nullptr, 0);