diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index c1c0de12a..e42b2bfb0 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -903,12 +903,16 @@ void MyHGC::reset_attributes() { attributes.multiplex = true; attributes.connection_warming = false; free(attributes.init_connect); + attributes.init_connect = NULL; free(attributes.comment); + attributes.comment = NULL; free(attributes.ignore_session_variables_text); + attributes.ignore_session_variables_text = NULL; attributes.ignore_session_variables_json = json(); } MyHGC::~MyHGC() { + reset_attributes(); // free all memory delete mysrvs; } @@ -1597,9 +1601,11 @@ void MySQL_HostGroups_Manager::CUCFT1(SpookyHash& myhash, bool& init, const stri } uint64_t hash1_ = resultset->raw_checksum(); myhash.Update(&hash1_, sizeof(hash1_)); - proxy_info("Checksum for table %s is %lu\n", TableName.c_str(), hash1_); + proxy_info("Checksum for table %s is 0x%lX\n", TableName.c_str(), hash1_); } delete resultset; + } else { + proxy_info("Checksum for table %s is 0x%lX\n", TableName.c_str(), (long unsigned int)0); } } @@ -1914,9 +1920,11 @@ bool MySQL_HostGroups_Manager::commit( } uint64_t hash1_ = resultset->raw_checksum(); myhash.Update(&hash1_, sizeof(hash1_)); - proxy_info("Checksum for table %s is %lu\n", "mysql_servers", hash1_); + proxy_info("Checksum for table %s is 0x%lX\n", "mysql_servers", hash1_); } delete resultset; + } else { + proxy_info("Checksum for table %s is 0x%lX\n", "mysql_servers", (long unsigned int)0); } } @@ -6444,7 +6452,6 @@ bool AWS_Aurora_Info::update(int r, int _port, char *_end_addr, int maxl, int al } void MySQL_HostGroups_Manager::generate_mysql_hostgroup_attributes_table() { -// TODO TODO TODO if (incoming_hostgroup_attributes==NULL) { return; } @@ -6455,7 +6462,7 @@ void MySQL_HostGroups_Manager::generate_mysql_hostgroup_attributes_table() { "hostgroup_id, max_num_online_servers, autocommit, free_connections_pct, " "init_connect, multiplex, connection_warming, throttle_connections_per_sec, " "ignore_session_variables, comment) VALUES " - "(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?8, ?10)"; + "(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)"; //rc=(*proxy_sqlite3_prepare_v2)(mydb3, query, -1, &statement, 0); rc = mydb->prepare_v2(query, &statement); @@ -6520,7 +6527,7 @@ void MySQL_HostGroups_Manager::generate_mysql_hostgroup_attributes_table() { myhgc->attributes.init_connect = strdup(init_connect); if (myhgc->attributes.comment != NULL) free(myhgc->attributes.comment); - myhgc->attributes.init_connect = strdup(comment); + myhgc->attributes.comment = strdup(comment); // for ignore_session_variables we store 2 versions: // 1. the text // 2. the JSON @@ -6540,7 +6547,6 @@ void MySQL_HostGroups_Manager::generate_mysql_hostgroup_attributes_table() { // TODO: assign the variables } } - break; } for (unsigned int i=0; ilen; i++) { MyHGC *myhgc=(MyHGC *)MyHostGroups->index(i); diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index e0aef211c..0da211bb5 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -4814,11 +4814,14 @@ void admin_session_handler(MySQL_Session *sess, void *_pa, PtrSize_t *pkt) { SPA->send_MySQL_ERR(&sess->client_myds->myprot, buf); run_query=false; } else if (resultset) { + l_free(query_length,query); char *q=(char *)"SELECT '%s' AS 'table', '%s' AS 'checksum'"; char *checksum=(char *)resultset->checksum(); query=(char *)malloc(strlen(q)+strlen(tablename)+strlen(checksum)+1); sprintf(query,q,tablename,checksum); + query_length = strlen(query); free(checksum); + delete resultset; } goto __run_query; } @@ -11781,7 +11784,7 @@ void ProxySQL_Admin::save_mysql_servers_runtime_to_database(bool _runtime) { StrQuery = "INSERT INTO "; if (_runtime) StrQuery += "runtime_"; - StrQuery += "mysql_hostgroup_attributes (hostgroup_id, max_num_online_servers, autocommit, free_connections_pct, init_connect, multiplex, connection_warming, throttle_connections_per_sec, ignore_session_variables, comment) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?8, ?10)"; + StrQuery += "mysql_hostgroup_attributes (hostgroup_id, max_num_online_servers, autocommit, free_connections_pct, init_connect, multiplex, connection_warming, throttle_connections_per_sec, ignore_session_variables, comment) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)"; rc = admindb->prepare_v2(StrQuery.c_str(), &statement); ASSERT_SQLITE_OK(rc, admindb); //proxy_info("New mysql_aws_aurora_hostgroups table\n"); @@ -11860,6 +11863,13 @@ void ProxySQL_Admin::load_mysql_servers_to_runtime( } else { MyHGM->servers_add(resultset_servers); } + // memory leak detected here + if (runtime_mysql_servers == nullptr) { + if (resultset_servers != nullptr) { + delete resultset_servers; + resultset_servers = nullptr; + } + } resultset=NULL; query=(char *)"SELECT a.* FROM mysql_replication_hostgroups a JOIN mysql_replication_hostgroups b ON a.writer_hostgroup=b.reader_hostgroup WHERE b.reader_hostgroup"; diff --git a/lib/ProxySQL_Cluster.cpp b/lib/ProxySQL_Cluster.cpp index 695a6415a..c70c3b895 100644 --- a/lib/ProxySQL_Cluster.cpp +++ b/lib/ProxySQL_Cluster.cpp @@ -1792,7 +1792,7 @@ void ProxySQL_Cluster::pull_mysql_servers_from_peer(const std::string& checksum, "hostgroup_id, max_num_online_servers, autocommit, free_connections_pct, " "init_connect, multiplex, connection_warming, throttle_connections_per_sec, " "ignore_session_variables, comment) VALUES " - "(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?8, ?10)"; + "(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)"; sqlite3_stmt *statement1 = NULL; int rc = GloAdmin->admindb->prepare_v2(q, &statement1); ASSERT_SQLITE_OK(rc, GloAdmin->admindb); diff --git a/test/cluster/check_all_nodes.bash b/test/cluster/check_all_nodes.bash index afae05d1e..1953e252e 100644 --- a/test/cluster/check_all_nodes.bash +++ b/test/cluster/check_all_nodes.bash @@ -1,5 +1,5 @@ #!/bin/bash -TABLES=(mysql_servers mysql_users mysql_query_rules mysql_query_rules_fast_routing global_variables proxysql_servers mysql_galera_hostgroups mysql_group_replication_hostgroups mysql_replication_hostgroups) +TABLES=(mysql_servers mysql_users mysql_query_rules mysql_query_rules_fast_routing global_variables proxysql_servers mysql_galera_hostgroups mysql_group_replication_hostgroups mysql_replication_hostgroups mysql_hostgroup_attributes) ALL_TABLES=() diff --git a/test/tap/tests/admin_various_commands2-t.cpp b/test/tap/tests/admin_various_commands2-t.cpp index 3f3b73da7..d38c2cc40 100644 --- a/test/tap/tests/admin_various_commands2-t.cpp +++ b/test/tap/tests/admin_various_commands2-t.cpp @@ -57,6 +57,7 @@ std::vector queries = { "CHECKSUM MEM MYSQL QUERY RULES", "CHECKSUM MEM MYSQL VARIABLES", "CHECKSUM MEM MYSQL REPLICATION HOSTGROUPS", + "CHECKSUM MEM MYSQL HOSTGROUP ATTRIBUTES", "CHECKSUM MEM MYSQL GROUP REPLICATION HOSTGROUPS", "CHECKSUM MEM MYSQL GALERA HOSTGROUPS", "CHECKSUM MEM MYSQL AURORA HOSTGROUPS", @@ -65,6 +66,7 @@ std::vector queries = { "CHECKSUM MEMORY MYSQL QUERY RULES", "CHECKSUM MEMORY MYSQL VARIABLES", "CHECKSUM MEMORY MYSQL REPLICATION HOSTGROUPS", + "CHECKSUM MEMORY MYSQL HOSTGROUP ATTRIBUTES", "CHECKSUM MEMORY MYSQL GROUP REPLICATION HOSTGROUPS", "CHECKSUM MEMORY MYSQL GALERA HOSTGROUPS", "CHECKSUM MEMORY MYSQL AURORA HOSTGROUPS", @@ -73,6 +75,7 @@ std::vector queries = { "CHECKSUM MYSQL QUERY RULES", "CHECKSUM MYSQL VARIABLES", "CHECKSUM MYSQL REPLICATION HOSTGROUPS", + "CHECKSUM MYSQL HOSTGROUP ATTRIBUTES", "CHECKSUM MYSQL GROUP REPLICATION HOSTGROUPS", "CHECKSUM MYSQL GALERA HOSTGROUPS", "CHECKSUM MYSQL AURORA HOSTGROUPS", diff --git a/test/tap/tests/test_mysql_hostgroup_attributes-1-t.cpp b/test/tap/tests/test_mysql_hostgroup_attributes-1-t.cpp new file mode 100644 index 000000000..f37be3912 --- /dev/null +++ b/test/tap/tests/test_mysql_hostgroup_attributes-1-t.cpp @@ -0,0 +1,103 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "tap.h" +#include "command_line.h" +#include "utils.h" + + +int run_queries_sets(std::vector& queries, MYSQL *my, const std::string& message_prefix) { + for (std::vector::iterator it = queries.begin(); it != queries.end(); it++) { + std::string q = *it; + diag("%s: %s", message_prefix.c_str(), q.c_str()); + MYSQL_QUERY(my, q.c_str()); + } + return 0; +} + +int check_checksum(MYSQL *mysqladmin, const char *expected_checksum, const char *when) { + MYSQL_QUERY(mysqladmin, "CHECKSUM MYSQL HOSTGROUP ATTRIBUTES"); + MYSQL_RES* result = mysql_store_result(mysqladmin); + ok(mysql_num_rows(result) == 1, "Line %d: CHECKSUM returned 1 row" , __LINE__); + if (mysql_num_rows(result) == 1) { + MYSQL_ROW row = mysql_fetch_row(result); + ok(strcmp(row[1],expected_checksum)==0, "Checksum %s: expected: %s, returned: %s", when, expected_checksum, row[1]); + } + mysql_free_result(result); + return 0; +} + +int run_one_test(MYSQL *mysqladmin, const char *expected_checksum, const char *query) { + std::vector queries = { "DELETE FROM mysql_hostgroup_attributes" }; + queries.push_back(std::string(query)); + queries.push_back("LOAD MYSQL SERVERS TO RUNTIME"); + if (run_queries_sets(queries, mysqladmin, "Running on Admin")) + return 1; + if (check_checksum(mysqladmin,expected_checksum,"before")) + return 1; + queries = { "DELETE FROM mysql_hostgroup_attributes", "SAVE MYSQL SERVERS FROM RUNTIME" }; + if (run_queries_sets(queries, mysqladmin, "Running on Admin")) + return 1; + if (check_checksum(mysqladmin,expected_checksum,"after")) + return 1; + return 0; +} + +int main(int argc, char** argv) { + CommandLine cl; + + if(cl.getEnv()) + return exit_status(); + + + std::unordered_map queries_and_checksums = { + { + "0x666CFBEEDB76EE9C", + "INSERT INTO mysql_hostgroup_attributes VALUES (19,1,1,10,'',1,1,10000,'','')" + }, + { + "0xE2FC2A5FEE8D18DC", + "INSERT INTO mysql_hostgroup_attributes VALUES (19,1,1,10,'',1,1,10000,'',''),(18,2,-1,20,'SET sql_mode=\"\"',0,0,100,'','hello world')", + }, + { + "0xFACE1C64FF1C373E", + "INSERT INTO mysql_hostgroup_attributes VALUES (19,1,1,10,'',1,1,10000,'',''),(18,2,-1,20,'SET sql_mode=\"\"',0,0,100,'','hello world'),(17,0,0,30,'SET long_query_time=0',1,0,123,'{\"session_variables\":[\"tmp_table_size\",\"join_buffer_size\"]}','filtering variables')" + }, + }; + + plan(queries_and_checksums.size()*4); + diag("Testing the loading of mysql_hostgroup_attributes"); + + MYSQL* mysqladmin = mysql_init(NULL); + if (!mysqladmin) + return exit_status(); + + if (!mysql_real_connect(mysqladmin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", + __FILE__, __LINE__, mysql_error(mysqladmin)); + return exit_status(); + } + + for (std::unordered_map::iterator it = queries_and_checksums.begin(); it != queries_and_checksums.end(); it++) { + if (run_one_test(mysqladmin, it->first.c_str() , it->second.c_str()) == 1) + return exit_status(); + auto it2 = it; + it2++; + if (it2 != queries_and_checksums.end()) { + diag("Sleeping 10 seconds because of Cluster"); + sleep(10); + } + } + mysql_close(mysqladmin); + + return exit_status(); +} +