Merge pull request #5150 from proton-lisandro-pin/ignore_min_gtid

Implement a `ignore_min_gtid_annotation` global variable, fix memory leak/overflow in `min_gtid` annotation handler.
v3.0_add_delay_tap_test
René Cannaò 4 months ago committed by GitHub
commit dfd46fee4b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -6,7 +6,7 @@
#include "query_processor.h"
class Command_Counter;
typedef struct _MySQL_Query_processor_Rule_t : public QP_rule_t {
typedef struct _MySQL_Query_processor_Rule_t : public QP_rule_t {
int gtid_from_hostgroup;
} MySQL_Query_Processor_Rule_t;
@ -75,14 +75,22 @@ private:
inline
void query_parser_first_comment_extended(const char* key, const char* value, MySQL_Query_Processor_Output* qpo) {
if (!strcasecmp(key, "min_gtid")) {
size_t l = strlen(value);
if (_is_valid_gtid((char*)value, l)) {
char* buf = (char*)malloc(l + 1);
strncpy(buf, value, l);
buf[l + 1] = '\0';
qpo->min_gtid = buf;
if (mysql_thread___ignore_min_gtid_annotations) {
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "Ignoring min_gtid=%s\n", value);
} else {
proxy_warning("Invalid gtid value=%s\n", value);
size_t l = strlen(value);
if (_is_valid_gtid((char*)value, l)) {
char* buf = (char*)malloc(l + 1);
strncpy(buf, value, l);
buf[l] = '\0';
if (qpo->min_gtid) {
free(qpo->min_gtid);
}
qpo->min_gtid = buf;
} else {
proxy_warning("Invalid min_gtid value=%s\n", value);
}
}
}
}

@ -577,6 +577,8 @@ class MySQL_Threads_Handler
#endif
int show_processlist_extended;
int processlist_max_query_length;
bool ignore_min_gtid_annotations;
} variables;
struct {
unsigned int mirror_sessions_current;

@ -1303,6 +1303,7 @@ __thread int mysql_thread___client_host_cache_size;
__thread int mysql_thread___client_host_error_counts;
__thread int mysql_thread___handle_warnings;
__thread int mysql_thread___evaluate_replication_lag_on_servers_load;
__thread bool mysql_thread___ignore_min_gtid_annotations;
/* variables used for Query Cache */
__thread int mysql_thread___query_cache_size_MB;
@ -1605,6 +1606,7 @@ extern __thread int mysql_thread___client_host_cache_size;
extern __thread int mysql_thread___client_host_error_counts;
extern __thread int mysql_thread___handle_warnings;
extern __thread int mysql_thread___evaluate_replication_lag_on_servers_load;
extern __thread bool mysql_thread___ignore_min_gtid_annotations;
/* variables used for Query Cache */
extern __thread int mysql_thread___query_cache_size_MB;

@ -7162,7 +7162,7 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
}
void MySQL_Session::handler___client_DSS_QUERY_SENT___server_DSS_NOT_INITIALIZED__get_connection() {
// Get a MySQL Connection
// Get a MySQL Connection
MySQL_Connection *mc=NULL;
MySQL_Backend * _gtid_from_backend = NULL;

@ -510,6 +510,7 @@ static char * mysql_thread_variables_names[]= {
(char *)"evaluate_replication_lag_on_servers_load",
(char *)"proxy_protocol_networks",
(char *)"protocol_compression_level",
(char *)"ignore_min_gtid_annotations",
NULL
};
@ -1149,6 +1150,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() {
variables.log_mysql_warnings_enabled=false;
variables.data_packets_history_size=0;
variables.protocol_compression_level=3;
variables.ignore_min_gtid_annotations=false;
// status variables
status_variables.mirror_sessions_current=0;
__global_MySQL_Thread_Variables_version=1;
@ -1373,6 +1375,7 @@ char * MySQL_Threads_Handler::get_variable_string(char *name) {
if (!strcmp(name,"keep_multiplexing_variables")) return strdup(variables.keep_multiplexing_variables);
if (!strcmp(name,"default_authentication_plugin")) return strdup(variables.default_authentication_plugin);
if (!strcmp(name,"proxy_protocol_networks")) return strdup(variables.proxy_protocol_networks);
// LCOV_EXCL_START
proxy_error("Not existing variable: %s\n", name); assert(0);
return NULL;
@ -2174,6 +2177,7 @@ char ** MySQL_Threads_Handler::get_variables_list() {
VariablesPointers_bool["stats_time_query_processor"] = make_tuple(&variables.stats_time_query_processor, false);
VariablesPointers_bool["use_tcp_keepalive"] = make_tuple(&variables.use_tcp_keepalive, false);
VariablesPointers_bool["verbose_query_error"] = make_tuple(&variables.verbose_query_error, false);
VariablesPointers_bool["ignore_min_gtid_annotations"] = make_tuple(&variables.ignore_min_gtid_annotations, false);
#ifdef IDLE_THREADS
VariablesPointers_bool["session_idle_show_processlist"] = make_tuple(&variables.session_idle_show_processlist, false);
#endif // IDLE_THREADS
@ -2294,16 +2298,16 @@ char ** MySQL_Threads_Handler::get_variables_list() {
VariablesPointers_int["eventslog_default_log"] = make_tuple(&variables.eventslog_default_log, 0, 1, false);
VariablesPointers_int["eventslog_stmt_parameters"] = make_tuple(&variables.eventslog_stmt_parameters, 0, 1, false);
// various
VariablesPointers_int["long_query_time"] = make_tuple(&variables.long_query_time, 0, 20*24*3600*1000, false);
VariablesPointers_int["max_allowed_packet"] = make_tuple(&variables.max_allowed_packet, 8192, 1024*1024*1024, false);
VariablesPointers_int["max_connections"] = make_tuple(&variables.max_connections, 1, 1000*1000, false);
VariablesPointers_int["max_stmts_per_connection"] = make_tuple(&variables.max_stmts_per_connection, 1, 1024, false);
VariablesPointers_int["max_stmts_cache"] = make_tuple(&variables.max_stmts_cache, 128, 1024*1024, false);
VariablesPointers_int["max_transaction_idle_time"] = make_tuple(&variables.max_transaction_idle_time, 1000, 20*24*3600*1000, false);
VariablesPointers_int["max_transaction_time"] = make_tuple(&variables.max_transaction_time, 1000, 20*24*3600*1000, false);
VariablesPointers_int["query_cache_size_mb"] = make_tuple(&variables.query_cache_size_MB, 0, 1024*10240, false);
VariablesPointers_int["query_cache_soft_ttl_pct"] = make_tuple(&variables.query_cache_soft_ttl_pct, 0, 100, false);
VariablesPointers_int["query_cache_handle_warnings"] = make_tuple(&variables.query_cache_handle_warnings, 0, 1, false);
VariablesPointers_int["long_query_time"] = make_tuple(&variables.long_query_time, 0, 20*24*3600*1000, false);
VariablesPointers_int["max_allowed_packet"] = make_tuple(&variables.max_allowed_packet, 8192, 1024*1024*1024, false);
VariablesPointers_int["max_connections"] = make_tuple(&variables.max_connections, 1, 1000*1000, false);
VariablesPointers_int["max_stmts_per_connection"] = make_tuple(&variables.max_stmts_per_connection, 1, 1024, false);
VariablesPointers_int["max_stmts_cache"] = make_tuple(&variables.max_stmts_cache, 128, 1024*1024, false);
VariablesPointers_int["max_transaction_idle_time"] = make_tuple(&variables.max_transaction_idle_time, 1000, 20*24*3600*1000, false);
VariablesPointers_int["max_transaction_time"] = make_tuple(&variables.max_transaction_time, 1000, 20*24*3600*1000, false);
VariablesPointers_int["query_cache_size_mb"] = make_tuple(&variables.query_cache_size_MB, 0, 1024*10240, false);
VariablesPointers_int["query_cache_soft_ttl_pct"] = make_tuple(&variables.query_cache_soft_ttl_pct, 0, 100, false);
VariablesPointers_int["query_cache_handle_warnings"] = make_tuple(&variables.query_cache_handle_warnings, 0, 1, false);
#ifdef IDLE_THREADS
VariablesPointers_int["session_idle_ms"] = make_tuple(&variables.session_idle_ms, 1, 3600*1000, false);
@ -4272,6 +4276,7 @@ void MySQL_Thread::refresh_variables() {
REFRESH_VARIABLE_INT(client_host_error_counts);
REFRESH_VARIABLE_INT(handle_warnings);
REFRESH_VARIABLE_INT(evaluate_replication_lag_on_servers_load);
REFRESH_VARIABLE_BOOL(ignore_min_gtid_annotations);
#ifdef DEBUG
REFRESH_VARIABLE_BOOL(session_debug);
#endif /* DEBUG */

@ -226,5 +226,6 @@
"test_ssl_fast_forward-2_libmariadb-t": [ "default-g4", "mysql-auto_increment_delay_multiplex=0-g4", "mysql-multiplexing=false-g4", "mysql-query_digests=0-g4", "mysql-query_digests_keep_comment=1-g4" ],
"test_ssl_fast_forward-2_libmysql-t": [ "default-g4", "mysql-auto_increment_delay_multiplex=0-g4", "mysql-multiplexing=false-g4", "mysql-query_digests=0-g4", "mysql-query_digests_keep_comment=1-g4" ],
"test_ssl_fast_forward-3_libmariadb-t": [ "default-g4", "mysql-auto_increment_delay_multiplex=0-g4", "mysql-multiplexing=false-g4", "mysql-query_digests=0-g4", "mysql-query_digests_keep_comment=1-g4" ],
"test_ssl_fast_forward-3_libmysql-t": [ "default-g4", "mysql-auto_increment_delay_multiplex=0-g4", "mysql-multiplexing=false-g4", "mysql-query_digests=0-g4", "mysql-query_digests_keep_comment=1-g4" ]
"test_ssl_fast_forward-3_libmysql-t": [ "default-g4", "mysql-auto_increment_delay_multiplex=0-g4", "mysql-multiplexing=false-g4", "mysql-query_digests=0-g4", "mysql-query_digests_keep_comment=1-g4" ],
"test_ignore_min_gtid-t": [ "default-g4", "mysql-auto_increment_delay_multiplex=0-g4", "mysql-multiplexing=false-g4", "mysql-query_digests=0-g4", "mysql-query_digests_keep_comment=1-g4" ]
}

@ -193,6 +193,9 @@ sqlite3-t: sqlite3-t.cpp $(TAP_LDIR)/libtap.so
test_gtid_forwarding-t: test_gtid_forwarding-t.cpp $(TAP_LDIR)/libtap.so
$(CXX) $< $(IDIRS) $(LDIRS) $(OPT) $(MYLIBS) -o $@
test_ignore_min_gtid-t: test_ignore_min_gtid-t.cpp $(TAP_LDIR)/libtap.so
$(CXX) $< $(IDIRS) $(LDIRS) $(OPT) $(MYLIBS) -o $@
test_admin_prometheus_metrics_dump-t: test_admin_prometheus_metrics_dump-t.cpp $(TAP_LDIR)/libtap.so
$(CXX) $< $(IDIRS) $(LDIRS) $(OPT) $(MYLIBS) -o $@

@ -0,0 +1,66 @@
/**
* @file test_ignore_min_gtid-t.cpp
* @brief This test file verifies the functionality of the mysql-ignore_min_gtid_annotations variable.
* - Sets mysql-ignore_min_gtid_annotations=true, so queries annotated with min_gtid succeed.
* - Sets mysql-ignore_min_gtid_annotations=false, so queries annotated with min_gtid fail.
*/
#include <stdio.h>
#include "command_line.h"
#include "mysql.h"
#include "tap.h"
#include "utils.h"
int main(int, char**) {
CommandLine cl;
if (cl.getEnv()) {
diag("Failed to get the required environmental variables.");
return -1;
}
plan(2);
MYSQL* admin = init_mysql_conn(cl.host, cl.admin_port, cl.admin_username, cl.admin_password);
if (!admin) {
fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(admin));
return exit_status();
}
MYSQL* proxy = init_mysql_conn(cl.host, cl.port, cl.username, cl.password);
if (!proxy) {
fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxy));
return exit_status();
}
const char *query = "SELECT /*+ ;min_gtid=01010101-0101-0101-0101-010101010101:101010101010 */ 1";
diag(" ========== Test 1 ==========");
MYSQL_QUERY_T(admin, "SET mysql-ignore_min_gtid_annotations = true");
MYSQL_QUERY_T(admin, "LOAD MYSQL VARIABLES TO RUNTIME");
int rc = run_q(proxy, query);
if (rc == 0) {
MYSQL_RES* result = mysql_store_result(proxy);
mysql_free_result(result);
}
ok(rc == 0, "Query execution should be successful. mysql-ignore_min_gtid_annotations=%s, rc=%d", "true", rc);
diag(" ========== Test 2 ==========");
MYSQL_QUERY_T(admin, "SET mysql-ignore_min_gtid_annotations = false");
MYSQL_QUERY_T(admin, "LOAD MYSQL VARIABLES TO RUNTIME");
rc = run_q(proxy, query);
if (rc == 0) {
MYSQL_RES* result = mysql_store_result(proxy);
mysql_free_result(result);
}
ok(rc != 0, "Query execution should fail. mysql-ignore_min_gtid_annotations=%s, rc=%d", "false", rc);
mysql_close(admin);
mysql_close(proxy);
return exit_status();
}
Loading…
Cancel
Save