Skip to content

Commit

Permalink
Merge pull request #4295 from sysown/v2.x-aurora_autodiscovery-refact…
Browse files Browse the repository at this point in the history
…or_cluster_mysql_servers-gr_bootstrap_mode

Merge of several PRs into single one
  • Loading branch information
renecannao authored Jan 15, 2024
2 parents 436fb08 + 9b00eb3 commit 2840e18
Show file tree
Hide file tree
Showing 28 changed files with 5,202 additions and 1,035 deletions.
15 changes: 13 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,13 @@ default: build_src
.PHONY: debug
debug: build_src_debug

.PHONY: testaurora_random
testaurora_random: build_src_testaurora_random

.PHONY: testaurora
testaurora: build_src_testaurora
cd test/tap && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA" CC=${CC} CXX=${CXX} ${MAKE}
cd test/tap/tests && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA" CC=${CC} CXX=${CXX} ${MAKE} $(MAKECMDGOALS)
# cd test/tap && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA" CC=${CC} CXX=${CXX} ${MAKE}
# cd test/tap/tests && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA" CC=${CC} CXX=${CXX} ${MAKE} $(MAKECMDGOALS)

.PHONY: testgalera
testgalera: build_src_testgalera
Expand Down Expand Up @@ -168,10 +171,18 @@ build_src_debug_legacy: build_lib_debug_legacy
build_src_testaurora: build_lib_testaurora
cd src && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA" CC=${CC} CXX=${CXX} ${MAKE}

.PHONY: build_src_testaurora_random
build_src_testaurora_random: build_lib_testaurora_random
cd src && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA -DTEST_AURORA_RANDOM" CC=${CC} CXX=${CXX} ${MAKE}

.PHONY: build_lib_testaurora
build_lib_testaurora: build_deps_debug
cd lib && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA" CC=${CC} CXX=${CXX} ${MAKE}

.PHONY: build_lib_testaurora_random
build_lib_testaurora_random: build_deps_debug
cd lib && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA -DTEST_AURORA_RANDOM" CC=${CC} CXX=${CXX} ${MAKE}

.PHONY: build_src_testgalera
build_src_testgalera: build_lib_testgalera
cd src && OPTZ="${O0} -ggdb -DDEBUG -DTEST_GALERA" CC=${CC} CXX=${CXX} ${MAKE}
Expand Down
222 changes: 222 additions & 0 deletions doc/proxysql_cluster/proxysql_cluster_working.md

Large diffs are not rendered by default.

305 changes: 299 additions & 6 deletions include/MySQL_HostGroups_Manager.h

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions include/MySQL_Monitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ A single AWS_Aurora_monitor_node will have a AWS_Aurora_status_entry per check.
*/

#ifdef TEST_AURORA

#define TEST_AURORA_MONITOR_BASE_QUERY \
"SELECT SERVER_ID, SESSION_ID, LAST_UPDATE_TIMESTAMP, REPLICA_LAG_IN_MILLISECONDS, CPU"\
" FROM REPLICA_HOST_STATUS ORDER BY SERVER_ID "

#endif

class AWS_Aurora_replica_host_status_entry {
public:
char * server_id = NULL;
Expand Down Expand Up @@ -200,6 +208,17 @@ enum class MySQL_Monitor_State_Data_Task_Result {
TASK_RESULT_PENDING
};

/**
* @brief Holds the info from a GR server definition.
*/
struct gr_host_def_t {
string host;
int port;
int use_ssl;
bool writer_is_also_reader;
int max_transactions_behind;
int max_transactions_behind_count;
};

class MySQL_Monitor_State_Data {
public:
Expand Down Expand Up @@ -237,6 +256,11 @@ class MySQL_Monitor_State_Data {
* @details Currently only used by 'group_replication'.
*/
uint64_t init_time = 0;
/**
* @brief Used by GroupReplication to determine if servers reported by cluster 'members' are already monitored.
* @details This way we avoid non-needed locking on 'MySQL_HostGroups_Manager' for server search.
*/
const std::vector<gr_host_def_t>* cur_monitored_gr_srvs = nullptr;

MySQL_Monitor_State_Data(MySQL_Monitor_State_Data_Task_Type task_type, char* h, int p, bool _use_ssl = 0, int g = 0);
~MySQL_Monitor_State_Data();
Expand Down
18 changes: 15 additions & 3 deletions include/MySQL_Session.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,21 @@ class MySQL_Session
bool handler_CommitRollback(PtrSize_t *);
bool handler_SetAutocommit(PtrSize_t *);
/**
* @brief Performs the cleanup of current session state, and the required operations to the supplied
* 'MySQL_Data_Stream' required for processing further queries.
* @param The 'MySQL_Data_Stream' which executed the previous query and which status should be updated.
* @brief Should execute most of the commands executed when a request is finalized.
* @details Cleanup of current session state, and required operations to the supplied 'MySQL_Data_Stream'
* for further queries processing. Takes care of the following actions:
* - Update the status of the backend connection (if supplied), with previous query actions.
* - Log the query for the required statuses.
* - Cleanup the previous Query_Processor output.
* - Free the resources of the backend connection (if supplied).
* - Reset all the required session status flags. E.g:
* + status
* + client_myds::DSS
* + started_sending_data_to_client
* + previous_hostgroup
* NOTE: Should become the place to hook other functions.
* @param myds If not null, should point to a MySQL_Data_Stream (backend connection) which connection status
* should be updated, and previous query resources cleanup.
*/
void RequestEnd(MySQL_Data_Stream *);
void LogQuery(MySQL_Data_Stream *);
Expand Down
84 changes: 60 additions & 24 deletions include/ProxySQL_Cluster.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,20 @@
* the queries issued for generating the checksum for each of the target modules, for simpler reasoning, they should
* also represent the actual resultset being received when issuing them, since this resultset is used for computing the
* 'expected checksum' for the fetched config before loading it to runtime. This is done for the following modules:
* - 'runtime_mysql_servers': tables 'mysql_servers', 'mysql_replication_hostgroups', 'mysql_group_replication_hostroups',
* 'mysql_galera_hostgroups', 'mysql_aws_aurora_hostgroups', 'mysql_hostgroup_attributes'.
* - 'runtime_mysql_servers': tables 'mysql_servers'
* - 'runtime_mysql_users'.
* - 'runtime_mysql_query_rules'.
*
* - 'mysql_servers_v2': tables admin 'mysql_servers', 'mysql_replication_hostgroups', 'mysql_group_replication_hostroups',
* 'mysql_galera_hostgroups', 'mysql_aws_aurora_hostgroups', 'mysql_hostgroup_attributes'.
* IMPORTANT: For further clarify this means that it's important that the actual resultset produced by the intercepted
* query preserve the filtering and ordering expressed in this queries.
*/

/* @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_mysql_servers'. See top comment for details. */
#define CLUSTER_QUERY_MYSQL_SERVERS "PROXY_SELECT hostgroup_id, hostname, port, gtid_port, status, weight, compression, max_connections, max_replication_lag, use_ssl, max_latency_ms, comment FROM runtime_mysql_servers WHERE status<>'OFFLINE_HARD' ORDER BY hostgroup_id, hostname, port"
#define CLUSTER_QUERY_RUNTIME_MYSQL_SERVERS "PROXY_SELECT hostgroup_id, hostname, port, gtid_port, status, weight, compression, max_connections, max_replication_lag, use_ssl, max_latency_ms, comment FROM runtime_mysql_servers WHERE status<>'OFFLINE_HARD' ORDER BY hostgroup_id, hostname, port"

/* @brief Query to be intercepted by 'ProxySQL_Admin' for 'mysql_servers_v2'. See top comment for details. */
#define CLUSTER_QUERY_MYSQL_SERVERS_V2 "PROXY_SELECT hostgroup_id, hostname, port, gtid_port, status, weight, compression, max_connections, max_replication_lag, use_ssl, max_latency_ms, comment FROM mysql_servers_v2 WHERE status<>'OFFLINE_HARD' ORDER BY hostgroup_id, hostname, port"

/* @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_mysql_replication_hostgroups'. See top comment for details. */
#define CLUSTER_QUERY_MYSQL_REPLICATION_HOSTGROUPS "PROXY_SELECT writer_hostgroup, reader_hostgroup, comment FROM runtime_mysql_replication_hostgroups ORDER BY writer_hostgroup"
Expand Down Expand Up @@ -189,6 +192,7 @@ class ProxySQL_Node_Entry {
ProxySQL_Checksum_Value_2 mysql_servers;
ProxySQL_Checksum_Value_2 mysql_users;
ProxySQL_Checksum_Value_2 proxysql_servers;
ProxySQL_Checksum_Value_2 mysql_servers_v2;
} checksums_values;
uint64_t global_checksum;
};
Expand Down Expand Up @@ -279,7 +283,9 @@ class ProxySQL_Cluster_Nodes {
SQLite3_result * stats_proxysql_servers_checksums();
SQLite3_result * stats_proxysql_servers_metrics();
void get_peer_to_sync_mysql_query_rules(char **host, uint16_t *port, char** ip_address);
void get_peer_to_sync_mysql_servers(char **host, uint16_t *port, char **peer_checksum, char** ip_address);
void get_peer_to_sync_runtime_mysql_servers(char **host, uint16_t *port, char **peer_checksum, char** ip_address);
void get_peer_to_sync_mysql_servers_v2(char** host, uint16_t* port, char** peer_mysql_servers_v2_checksum,
char** peer_runtime_mysql_servers_checksum, char** ip_address);
void get_peer_to_sync_mysql_users(char **host, uint16_t *port, char** ip_address);
void get_peer_to_sync_mysql_variables(char **host, uint16_t *port, char** ip_address);
void get_peer_to_sync_admin_variables(char **host, uint16_t* port, char** ip_address);
Expand Down Expand Up @@ -366,6 +372,31 @@ struct variable_type {
};
};

/**
* @brief Specifies the sync algorithm to use when pulling config from another ProxySQL cluster peer.
*/
enum class mysql_servers_sync_algorithm {
/**
* @brief Sync 'runtime_mysql_servers' and 'mysql_server_v2' from remote peer.
* @details This means that both config and runtime servers info are to be synced, in other words, both
* user promoted config and runtime changes performed by ProxySQL ('Monitor') in the remote peer will
* trigger the start of syncing operations.
*/
runtime_mysql_servers_and_mysql_servers_v2 = 1,
/**
* @brief Sync only mysql_server_v2 (config) from the remote peer.
* @details Since 'runtime_mysql_servers' isn't considered for fetching, only config changes promoted by
* the user in the remote peer will by acknowledge and trigger the start of a syncing operation.
*/
mysql_servers_v2 = 2,
/**
* @brief Dependent on whether ProxySQL has been started with the -M flag.
* @details If '-M' is not present, 'runtime_mysql_servers_and_mysql_servers_v2' is selected, otherwise
* 'mysql_servers_v2' is chosen.
*/
auto_select = 3
};

/**
* @brief Simple struct for holding a query, and three messages to report
* the progress of the query execution.
Expand All @@ -378,21 +409,23 @@ struct fetch_query {
};

class ProxySQL_Cluster {
private:
private:
SQLite3DB* mydb;
pthread_mutex_t mutex;
std::vector<pthread_t> term_threads;
ProxySQL_Cluster_Nodes nodes;
char *cluster_username;
char *cluster_password;
char* cluster_username;
char* cluster_password;
struct {
std::array<prometheus::Counter*, p_cluster_counter::__size> p_counter_array {};
std::array<prometheus::Gauge*, p_cluster_gauge::__size> p_gauge_array {};
std::array<prometheus::Counter*, p_cluster_counter::__size> p_counter_array{};
std::array<prometheus::Gauge*, p_cluster_gauge::__size> p_gauge_array{};
} metrics;
int fetch_and_store(MYSQL* conn, const fetch_query& f_query, MYSQL_RES** result);
friend class ProxySQL_Node_Entry;
public:
public:
pthread_mutex_t update_mysql_query_rules_mutex;
pthread_mutex_t update_mysql_servers_mutex;
pthread_mutex_t update_runtime_mysql_servers_mutex;
pthread_mutex_t update_mysql_servers_v2_mutex;
pthread_mutex_t update_mysql_users_mutex;
pthread_mutex_t update_mysql_variables_mutex;
pthread_mutex_t update_proxysql_servers_mutex;
Expand All @@ -407,7 +440,7 @@ class ProxySQL_Cluster {
*/
SQLite3_result* proxysql_servers_to_monitor;

char *admin_mysql_ifaces;
char* admin_mysql_ifaces;
int cluster_check_interval_ms;
int cluster_check_status_frequency;
int cluster_mysql_query_rules_diffs_before_sync;
Expand All @@ -417,6 +450,7 @@ class ProxySQL_Cluster {
int cluster_mysql_variables_diffs_before_sync;
int cluster_ldap_variables_diffs_before_sync;
int cluster_admin_variables_diffs_before_sync;
int cluster_mysql_servers_sync_algorithm;
bool cluster_mysql_query_rules_save_to_disk;
bool cluster_mysql_servers_save_to_disk;
bool cluster_mysql_users_save_to_disk;
Expand All @@ -428,7 +462,7 @@ class ProxySQL_Cluster {
~ProxySQL_Cluster();
void init() {};
void print_version();
void load_servers_list(SQLite3_result *r, bool _lock = true) {
void load_servers_list(SQLite3_result* r, bool _lock = true) {
nodes.load_servers_list(r, _lock);
}
void update_table_proxysql_servers_for_monitor(SQLite3_result* resultset) {
Expand All @@ -440,17 +474,17 @@ class ProxySQL_Cluster {

MySQL_Monitor::trigger_dns_cache_update();
}
void get_credentials(char **, char **);
void set_username(char *);
void set_password(char *);
void set_admin_mysql_ifaces(char *);
bool Update_Node_Metrics(char * _h, uint16_t _p, MYSQL_RES *_r, unsigned long long _response_time) {
void get_credentials(char**, char**);
void set_username(char*);
void set_password(char*);
void set_admin_mysql_ifaces(char*);
bool Update_Node_Metrics(char* _h, uint16_t _p, MYSQL_RES* _r, unsigned long long _response_time) {
return nodes.Update_Node_Metrics(_h, _p, _r, _response_time);
}
bool Update_Global_Checksum(char * _h, uint16_t _p, MYSQL_RES *_r) {
bool Update_Global_Checksum(char* _h, uint16_t _p, MYSQL_RES* _r) {
return nodes.Update_Global_Checksum(_h, _p, _r);
}
bool Update_Node_Checksums(char * _h, uint16_t _p, MYSQL_RES *_r = NULL) {
bool Update_Node_Checksums(char* _h, uint16_t _p, MYSQL_RES* _r = NULL) {
return nodes.Update_Node_Checksums(_h, _p, _r);
}
void Reset_Global_Checksums(bool lock) {
Expand All @@ -459,17 +493,19 @@ class ProxySQL_Cluster {
SQLite3_result *dump_table_proxysql_servers() {
return nodes.dump_table_proxysql_servers();
}
SQLite3_result * get_stats_proxysql_servers_checksums() {
SQLite3_result* get_stats_proxysql_servers_checksums() {
return nodes.stats_proxysql_servers_checksums();
}
SQLite3_result * get_stats_proxysql_servers_metrics() {
SQLite3_result* get_stats_proxysql_servers_metrics() {
return nodes.stats_proxysql_servers_metrics();
}
void p_update_metrics();
void thread_ending(pthread_t);
void join_term_thread();
void pull_mysql_query_rules_from_peer(const std::string& expected_checksum, const time_t epoch);
void pull_mysql_servers_from_peer(const std::string& expected_checksum, const time_t epoch);
void pull_runtime_mysql_servers_from_peer(const runtime_mysql_servers_checksum_t& peer_runtime_mysql_server);
void pull_mysql_servers_v2_from_peer(const mysql_servers_v2_checksum_t& peer_mysql_server_v2,
const runtime_mysql_servers_checksum_t& peer_runtime_mysql_server = {}, bool fetch_runtime_mysql_servers = false);
void pull_mysql_users_from_peer(const std::string& expected_checksum, const time_t epoch);
/**
* @brief Pulls from peer the specified global variables by the type parameter.
Expand Down
10 changes: 8 additions & 2 deletions include/SQLite3_Server.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "proxysql.h"
#include "cpp.h"
#include <vector>
#include <string>

class SQLite3_Session {
public:
Expand All @@ -14,7 +15,7 @@ class SQLite3_Session {
};

#ifdef TEST_GROUPREP
using group_rep_status = std::tuple<bool, bool, uint32_t>;
using group_rep_status = std::tuple<bool, bool, uint32_t, std::string>;
#endif

class SQLite3_Server {
Expand Down Expand Up @@ -70,7 +71,12 @@ class SQLite3_Server {
unsigned int num_aurora_servers[3];
unsigned int max_num_aurora_servers;
pthread_mutex_t aurora_mutex;
void populate_aws_aurora_table(MySQL_Session *sess);
/**
* @brief Handles queries to table 'REPLICA_HOST_STATUS'.
* @details This function needs to be called with lock on mutex aurora_mutex already acquired.
* @param sess The session which request is to be handled.
*/
void populate_aws_aurora_table(MySQL_Session *sess, uint32_t whg);
void init_aurora_ifaces_string(std::string& s);
#endif // TEST_AURORA
#ifdef TEST_GALERA
Expand Down
Loading

0 comments on commit 2840e18

Please sign in to comment.