Merge branch 'v2.0.4' of https://github.com/sysown/proxysql into v2.0.4

v2.0.4
René Cannaò 7 years ago
commit 8564179559

@ -42,6 +42,15 @@ default: build_deps build_lib build_src
.PHONY: debug
debug: build_deps_debug build_lib_debug build_src_debug
.PHONY: testaurora
testaurora: build_deps_debug build_lib_testaurora build_src_testaurora
.PHONY: testgalera
testgalera: build_deps_debug build_lib_testgalera build_src_testgalera
.PHONY: testall
testall: build_deps_debug build_lib_testall build_src_testall
.PHONY: clickhouse
clickhouse: build_deps_clickhouse build_lib_clickhouse build_src_clickhouse
@ -69,6 +78,30 @@ build_deps_debug:
build_lib_debug: build_deps_debug
cd lib && OPTZ="${O0} -ggdb -DDEBUG" CC=${CC} CXX=${CXX} ${MAKE}
.PHONY: build_src_testaurora
build_src_testaurora: build_deps build_lib_testaurora
cd src && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA" 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_src_testgalera
build_src_testgalera: build_deps build_lib_testgalera
cd src && OPTZ="${O0} -ggdb -DDEBUG -DTEST_GALERA" CC=${CC} CXX=${CXX} ${MAKE}
.PHONY: build_lib_testgalera
build_lib_testgalera: build_deps_debug
cd lib && OPTZ="${O0} -ggdb -DDEBUG -DTEST_GALERA" CC=${CC} CXX=${CXX} ${MAKE}
.PHONY: build_src_testall
build_src_testall: build_deps build_lib_testall
cd src && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA -DTEST_GALERA" CC=${CC} CXX=${CXX} ${MAKE}
.PHONY: build_lib_testall
build_lib_testall: build_deps_debug
cd lib && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA -DTEST_GALERA" CC=${CC} CXX=${CXX} ${MAKE}
.PHONY: build_src_debug
build_src_debug: build_deps build_lib_debug
cd src && OPTZ="${O0} -ggdb -DDEBUG" CC=${CC} CXX=${CXX} ${MAKE}

@ -36,6 +36,9 @@
#define MYHGM_MYSQL_GALERA_HOSTGROUPS "CREATE TABLE mysql_galera_hostgroups (writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY , backup_writer_hostgroup INT CHECK (backup_writer_hostgroup>=0 AND backup_writer_hostgroup<>writer_hostgroup) NOT NULL , reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND backup_writer_hostgroup<>reader_hostgroup AND reader_hostgroup>0) , offline_hostgroup INT NOT NULL CHECK (offline_hostgroup<>writer_hostgroup AND offline_hostgroup<>reader_hostgroup AND backup_writer_hostgroup<>offline_hostgroup AND offline_hostgroup>=0) , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , max_writers INT NOT NULL CHECK (max_writers >= 0) DEFAULT 1 , writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1,2)) NOT NULL DEFAULT 0 , max_transactions_behind INT CHECK (max_transactions_behind>=0) NOT NULL DEFAULT 0 , comment VARCHAR , UNIQUE (reader_hostgroup) , UNIQUE (offline_hostgroup) , UNIQUE (backup_writer_hostgroup))"
#define MYHGM_MYSQL_AWS_AURORA_HOSTGROUPS "CREATE TABLE mysql_aws_aurora_hostgroups (writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY , reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND reader_hostgroup>0) , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , aurora_port INT NOT NUlL DEFAULT 3306 , endpoint_address VARCHAR NOT NULL DEFAULT '' , max_lag_ms INT NOT NULL CHECK (max_lag_ms>= 10 AND max_lag_ms <= 600000) DEFAULT 600000 , check_interval_ms INT NOT NULL CHECK (check_interval_ms >= 100 AND check_interval_ms <= 600000) DEFAULT 1000 , check_timeout_ms INT NOT NULL CHECK (check_timeout_ms >= 80 AND check_timeout_ms <= 3000) DEFAULT 800 , writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1)) NOT NULL DEFAULT 0 , new_reader_weight INT CHECK (new_reader_weight >= 0 AND new_reader_weight <=10000000) NOT NULL DEFAULT 1 , comment VARCHAR , UNIQUE (reader_hostgroup))"
typedef std::unordered_map<std::uint64_t, void *> umap_mysql_errors;
class MySrvConnList;
@ -321,6 +324,7 @@ class MySrvC { // MySQL Server Container
enum MySerStatus status;
unsigned int compression;
unsigned int max_connections;
unsigned int aws_aurora_current_lag_us;
unsigned int max_replication_lag;
unsigned int max_connections_used; // The maximum number of connections that has been opened
unsigned int connect_OK;
@ -380,7 +384,7 @@ class MyHGC { // MySQL Host Group Container
MySrvList *mysrvs;
MyHGC(int);
~MyHGC();
MySrvC *get_random_MySrvC(char * gtid_uuid, uint64_t gtid_trxid);
MySrvC *get_random_MySrvC(char * gtid_uuid, uint64_t gtid_trxid, int max_lag_ms, MySQL_Session *sess);
};
class Group_Replication_Info {
@ -427,6 +431,27 @@ class Galera_Info {
~Galera_Info();
};
class AWS_Aurora_Info {
public:
int writer_hostgroup;
int reader_hostgroup;
int aurora_port;
int max_lag_ms;
int check_interval_ms;
int check_timeout_ms;
int writer_is_also_reader;
int new_reader_weight;
// TODO
// add intermediary status value, for example the last check time
char * endpoint_address;
char * comment;
bool active;
bool __active;
AWS_Aurora_Info(int w, int r, int _port, char *_end_addr, int ml, int ci, int ct, bool _a, int wiar, int nrw, char *c);
bool update(int r, int _port, char *_end_addr, int ml, int ci, int ct, bool _a, int wiar, int nrw, char *c);
~AWS_Aurora_Info();
};
class MySQL_HostGroups_Manager {
private:
SQLite3DB *admindb;
@ -460,6 +485,12 @@ class MySQL_HostGroups_Manager {
pthread_mutex_t Galera_Info_mutex;
std::map<int , Galera_Info *> Galera_Info_Map;
void generate_mysql_aws_aurora_hostgroups_table();
SQLite3_result *incoming_aws_aurora_hostgroups;
pthread_mutex_t AWS_Aurora_Info_mutex;
std::map<int , AWS_Aurora_Info *> AWS_Aurora_Info_Map;
std::thread *HGCU_thread;
std::thread *GTID_syncer_thread;
@ -523,16 +554,18 @@ class MySQL_HostGroups_Manager {
void set_incoming_replication_hostgroups(SQLite3_result *);
void set_incoming_group_replication_hostgroups(SQLite3_result *);
void set_incoming_galera_hostgroups(SQLite3_result *);
void set_incoming_aws_aurora_hostgroups(SQLite3_result *);
SQLite3_result * execute_query(char *query, char **error);
SQLite3_result *dump_table_mysql_servers();
SQLite3_result *dump_table_mysql_replication_hostgroups();
SQLite3_result *dump_table_mysql_group_replication_hostgroups();
SQLite3_result *dump_table_mysql_galera_hostgroups();
SQLite3_result *dump_table_mysql_aws_aurora_hostgroups();
MyHGC * MyHGC_lookup(unsigned int);
void MyConn_add_to_pool(MySQL_Connection *);
MySQL_Connection * get_MyConn_from_pool(unsigned int hid, MySQL_Session *sess, bool ff, char * gtid_uuid, uint64_t gtid_trxid);
MySQL_Connection * get_MyConn_from_pool(unsigned int hid, MySQL_Session *sess, bool ff, char * gtid_uuid, uint64_t gtid_trxid, int max_lag_ms);
void drop_all_idle_connections();
int get_multiple_idle_connections(int, unsigned long long, MySQL_Connection **, int);
@ -561,6 +594,15 @@ class MySQL_HostGroups_Manager {
void update_galera_set_writer(char *_hostname, int _port, int _writer_hostgroup);
void converge_galera_config(int _writer_hostgroup);
// FIXME : add action functions for AWS Aurora
//void aws_aurora_replication_lag_action(int _whid, int _rhid, char *address, unsigned int port, float current_replication_lag, bool enable, bool verbose=true);
//bool aws_aurora_replication_lag_action(int _whid, int _rhid, char *address, unsigned int port, unsigned int current_replication_lag_us, bool enable, bool is_writer, bool verbose=true);
//void update_aws_aurora_set_writer(int _whid, int _rhid, char *address, unsigned int port, bool verbose=true);
//void update_aws_aurora_set_reader(int _whid, int _rhid, char *_hostname, int _port);
bool aws_aurora_replication_lag_action(int _whid, int _rhid, char *server_id, float current_replication_lag_ms, bool enable, bool is_writer, bool verbose=true);
void update_aws_aurora_set_writer(int _whid, int _rhid, char *server_id, bool verbose=true);
void update_aws_aurora_set_reader(int _whid, int _rhid, char *server_id);
SQLite3_result * get_stats_mysql_gtid_executed();
void generate_mysql_gtid_executed_tables();
bool gtid_exists(MySrvC *mysrvc, char * gtid_uuid, uint64_t gtid_trxid);

@ -5,7 +5,6 @@
#include "thread.h"
#include "wqueue.h"
//#define MONITOR_SQLITE_TABLE_MYSQL_SERVER_CONNECT "CREATE TABLE mysql_server_connect (hostname VARCHAR NOT NULL , port INT NOT NULL DEFAULT 3306 , time_since INT NOT NULL DEFAULT 0 , time_until INT NOT NULL DEFAULT 0 , connect_success_count INT NOT NULL DEFAULT 0 , connect_success_first INT NOT NULL DEFAULT 0 , connect_success_last INT NOT NULL DEFAULT 0 , connect_success_time_min INT NOT NULL DEFAULT 0 , connect_success_time_max INT NOT NULL DEFAULT 0 , connect_success_time_total INT NOT NULL DEFAULT 0 , connect_failure_count INT NOT NULL DEFAULT 0 , connect_failure_first INT NOT NULL DEFAULT 0 , connect_failure_last INT NOT NULL DEFAULT 0 , PRIMARY KEY (hostname, port))"
//#define MONITOR_SQLITE_TABLE_MYSQL_SERVER_PING "CREATE TABLE mysql_server_ping (hostname VARCHAR NOT NULL , port INT NOT NULL DEFAULT 3306 , time_since INT NOT NULL DEFAULT 0 , time_until INT NOT NULL DEFAULT 0 , ping_success_count INT NOT NULL DEFAULT 0 , ping_success_first INT NOT NULL DEFAULT 0, ping_success_last INT NOT NULL DEFAULT 0 , ping_success_time_min INT NOT NULL DEFAULT 0 , ping_success_time_max INT NOT NULL DEFAULT 0 , ping_success_time_total INT NOT NULL DEFAULT 0 , ping_failure_count INT NOT NULL DEFAULT 0 , ping_failure_first INT NOT NULL DEFAULT 0 , ping_failure_last INT NOT NULL DEFAULT 0 , PRIMARY KEY (hostname, port))"
@ -23,6 +22,14 @@
//#define MONITOR_SQLITE_TABLE_MYSQL_SERVER_GALERA_LOG "CREATE TABLE mysql_server_galera_log (hostname VARCHAR NOT NULL , port INT NOT NULL DEFAULT 3306 , time_start_us INT NOT NULL DEFAULT 0 , success_time_us INT DEFAULT 0 , viable_candidate VARCHAR NOT NULL DEFAULT 'NO' , read_only VARCHAR NOT NULL DEFAULT 'YES' , transactions_behind INT DEFAULT 0 , error VARCHAR , PRIMARY KEY (hostname, port, time_start_us))"
#define MONITOR_SQLITE_TABLE_MYSQL_SERVER_GALERA_LOG "CREATE TABLE mysql_server_galera_log (hostname VARCHAR NOT NULL , port INT NOT NULL DEFAULT 3306 , time_start_us INT NOT NULL DEFAULT 0 , success_time_us INT DEFAULT 0 , primary_partition VARCHAR NOT NULL DEFAULT 'NO' , read_only VARCHAR NOT NULL DEFAULT 'YES' , wsrep_local_recv_queue INT DEFAULT 0 , wsrep_local_state INT DEFAULT 0 , wsrep_desync VARCHAR NOT NULL DEFAULT 'NO' , wsrep_reject_queries VARCHAR NOT NULL DEFAULT 'NO' , wsrep_sst_donor_rejects_queries VARCHAR NOT NULL DEFAULT 'NO' , error VARCHAR , PRIMARY KEY (hostname, port, time_start_us))"
//#define MONITOR_SQLITE_TABLE_MYSQL_SERVER_AWS_AURORA_LOG "CREATE TABLE mysql_server_aws_aurora_log (hostname VARCHAR NOT NULL , port INT NOT NULL DEFAULT 3306 , time_start_us INT NOT NULL DEFAULT 0 , success_time_us INT DEFAULT 0 , error VARCHAR , SERVER_ID VARCHAR NOT NULL DEFAULT '' , SESSION_ID VARCHAR NOT NULL DEFAULT '' , LAST_UPDATE_TIMESTAMP VARCHAR NOT NULL DEFAULT '' , replica_lag_in_microseconds INT NOT NULL DEFAULT 0 , CPU INT NOT NULL DEFAULT 0 , PRIMARY KEY (hostname, port, time_start_us, SERVER_ID))"
#define MONITOR_SQLITE_TABLE_MYSQL_SERVER_AWS_AURORA_LOG "CREATE TABLE mysql_server_aws_aurora_log (hostname VARCHAR NOT NULL , port INT NOT NULL DEFAULT 3306 , time_start_us INT NOT NULL DEFAULT 0 , success_time_us INT DEFAULT 0 , error VARCHAR , SERVER_ID VARCHAR NOT NULL DEFAULT '' , SESSION_ID VARCHAR , LAST_UPDATE_TIMESTAMP VARCHAR , replica_lag_in_milliseconds INT NOT NULL DEFAULT 0 , CPU INT NOT NULL DEFAULT 0 , PRIMARY KEY (hostname, port, time_start_us, SERVER_ID))"
#define MONITOR_SQLITE_TABLE_MYSQL_SERVER_AWS_AURORA_CHECK_STATUS "CREATE TABLE mysql_server_aws_aurora_check_status (writer_hostgroup INT NOT NULL , hostname VARCHAR NOT NULL , port INT NOT NULL DEFAULT 3306 , last_checked_at VARCHAR , checks_tot INT NOT NULL DEFAULT 0 , checks_ok INT NOT NULL DEFAULT 0 , last_error VARCHAR , PRIMARY KEY (writer_hostgroup, hostname, port))"
#define MONITOR_SQLITE_TABLE_MYSQL_SERVER_AWS_AURORA_FAILOVERS "CREATE TABLE mysql_server_aws_aurora_failovers (writer_hostgroup INT NOT NULL , hostname VARCHAR NOT NULL , inserted_at VARCHAR NOT NULL)"
/*
struct cmp_str {
bool operator()(char const *a, char const *b) const
@ -34,6 +41,65 @@ struct cmp_str {
#define MyGR_Nentries 100
#define Galera_Nentries 100
#define AWS_Aurora_Nentries 50
#define N_L_ASE 8
/*
Implementation of monitoring in AWS Aurora will be different than previous modules
AWS_Aurora_replica_host_status_entry represents a single row returned from AWS_Aurora_replica_host_status_entry
AWS_Aurora_status_entry represents a single check executed against a single Aurora node.
AWS_Aurora_status_entry can contain several AWS_Aurora_replica_host_status_entry
AWS_Aurora_monitor_node represents a single Aurora node where checks are executed.
A single AWS_Aurora_monitor_node will have a AWS_Aurora_status_entry per check.
*/
class AWS_Aurora_replica_host_status_entry {
public:
char * server_id;
char * session_id;
char * last_update_timestamp;
float replica_lag_ms; // originally a double
float cpu;
AWS_Aurora_replica_host_status_entry(char *serid, char *sessid, char * lut, float rlm, float _c);
AWS_Aurora_replica_host_status_entry(char *serid, char *sessid, char * lut, char * rlm, char * _c);
~AWS_Aurora_replica_host_status_entry();
};
class AWS_Aurora_status_entry {
public:
unsigned long long start_time;
unsigned long long check_time;
char *error;
std::vector<AWS_Aurora_replica_host_status_entry *> * host_statuses;
AWS_Aurora_status_entry(unsigned long long st, unsigned long long ct, char *e);
void add_host_status(AWS_Aurora_replica_host_status_entry *hs);
~AWS_Aurora_status_entry();
};
class AWS_Aurora_monitor_node {
private:
int idx_last_entry;
public:
char *addr;
int port;
unsigned int writer_hostgroup;
uint64_t num_checks_tot;
uint64_t num_checks_ok;
time_t last_checked_at;
AWS_Aurora_status_entry *last_entries[AWS_Aurora_Nentries];
AWS_Aurora_monitor_node(char *_a, int _p, int _whg);
~AWS_Aurora_monitor_node();
bool add_entry(AWS_Aurora_status_entry *ase); // return true if status changed
AWS_Aurora_status_entry *last_entry() {
if (idx_last_entry == -1) return NULL;
return (last_entries[idx_last_entry]);
}
};
typedef struct _Galera_status_entry_t {
unsigned long long start_time;
@ -115,6 +181,8 @@ class MySQL_Monitor_State_Data {
int writer_hostgroup; // used only by group replication
bool writer_is_also_reader; // used only by group replication
int max_transactions_behind; // used only by group replication
int aws_aurora_max_lag_ms;
int aws_aurora_check_timeout_ms;
bool use_ssl;
MYSQL *mysql;
MYSQL_RES *result;
@ -153,11 +221,15 @@ class MySQL_Monitor {
public:
pthread_mutex_t group_replication_mutex; // for simplicity, a mutex instead of a rwlock
pthread_mutex_t galera_mutex; // for simplicity, a mutex instead of a rwlock
pthread_mutex_t aws_aurora_mutex; // for simplicity, a mutex instead of a rwlock
//std::map<char *, MyGR_monitor_node *, cmp_str> Group_Replication_Hosts_Map;
std::map<std::string, MyGR_monitor_node *> Group_Replication_Hosts_Map;
SQLite3_result *Group_Replication_Hosts_resultset;
std::map<std::string, Galera_monitor_node *> Galera_Hosts_Map;
SQLite3_result *Galera_Hosts_resultset;
std::map<std::string, AWS_Aurora_monitor_node *> AWS_Aurora_Hosts_Map;
SQLite3_result *AWS_Aurora_Hosts_resultset;
uint64_t AWS_Aurora_Hosts_resultset_checksum;
unsigned int num_threads;
unsigned int aux_threads;
unsigned int started_threads;
@ -172,6 +244,7 @@ class MySQL_Monitor {
wqueue<WorkItem*> * queue = NULL;
MySQL_Monitor_Connection_Pool *My_Conn_Pool;
bool shutdown;
pthread_mutex_t mon_en_mutex;
bool monitor_enabled;
SQLite3DB *admindb; // internal database
SQLite3DB *monitordb; // internal database
@ -183,13 +256,19 @@ class MySQL_Monitor {
void * monitor_read_only();
void * monitor_group_replication();
void * monitor_galera();
void * monitor_aws_aurora();
void * monitor_replication_lag();
void * run();
void populate_monitor_mysql_server_group_replication_log();
void populate_monitor_mysql_server_galera_log();
void populate_monitor_mysql_server_aws_aurora_log();
void populate_monitor_mysql_server_aws_aurora_check_status();
char * galera_find_last_node(int);
std::vector<string> * galera_find_possible_last_nodes(int);
bool server_responds_to_ping(char *address, int port);
// FIXME : add AWS Aurora actions
void evaluate_aws_aurora_results(unsigned int wHG, unsigned int rHG, AWS_Aurora_status_entry **lasts_ase, unsigned int ase_idx, unsigned int max_latency_ms);
// void gdb_dump___monitor_mysql_server_aws_aurora_log(char *hostname);
};
#endif /* __CLASS_MYSQL_MONITOR_H */

@ -227,6 +227,7 @@ class MySQL_Thread
unsigned long long queries;
unsigned long long queries_slow;
unsigned long long queries_gtid;
unsigned long long queries_with_max_lag_ms;
unsigned long long queries_backends_bytes_sent;
unsigned long long queries_backends_bytes_recv;
unsigned long long queries_frontends_bytes_sent;
@ -239,18 +240,23 @@ class MySQL_Thread
unsigned long long ConnPool_get_conn_immediate;
unsigned long long ConnPool_get_conn_success;
unsigned long long ConnPool_get_conn_failure;
unsigned long long ConnPool_get_conn_latency_awareness;
unsigned long long gtid_binlog_collected;
unsigned long long gtid_session_collected;
unsigned long long generated_pkt_err;
unsigned long long max_connect_timeout_err;
unsigned long long backend_lagging_during_query;
unsigned long long backend_offline_during_query;
unsigned long long unexpected_com_quit;
unsigned long long unexpected_packet;
unsigned long long killed_connections;
unsigned long long killed_queries;
unsigned long long aws_aurora_replicas_skipped_during_query;
unsigned int active_transactions;
} status_variables;
struct {
int min_num_servers_lantency_awareness;
bool stats_time_backend_query;
bool stats_time_query_processor;
bool query_cache_stores_empty_result;
@ -274,7 +280,7 @@ class MySQL_Thread
void unregister_session_connection_handler(int idx, bool _new=false);
void listener_handle_new_connection(MySQL_Data_Stream *myds, unsigned int n);
void Get_Memory_Stats();
MySQL_Connection * get_MyConn_local(unsigned int, MySQL_Session *sess, char *gtid_uuid, uint64_t gtid_trxid);
MySQL_Connection * get_MyConn_local(unsigned int, MySQL_Session *sess, char *gtid_uuid, uint64_t gtid_trxid, int max_lag_ms);
void push_MyConn_local(MySQL_Connection *);
void return_local_connections();
void Scan_Sessions_to_Kill(PtrArray *mysess);
@ -347,6 +353,7 @@ class MySQL_Threads_Handler
int monitor_groupreplication_healthcheck_timeout;
int monitor_galera_healthcheck_interval;
int monitor_galera_healthcheck_timeout;
int monitor_galera_healthcheck_max_timeout_count;
int monitor_query_interval;
int monitor_query_timeout;
int monitor_slave_lag_when_null;
@ -442,6 +449,7 @@ class MySQL_Threads_Handler
char * ssl_p2s_key;
char * ssl_p2s_cipher;
int query_cache_size_MB;
int min_num_servers_lantency_awareness;
bool stats_time_backend_query;
bool stats_time_query_processor;
bool query_cache_stores_empty_result;
@ -512,10 +520,15 @@ class MySQL_Threads_Handler
unsigned long long get_ConnPool_get_conn_immediate();
unsigned long long get_ConnPool_get_conn_success();
unsigned long long get_ConnPool_get_conn_failure();
unsigned long long get_ConnPool_get_conn_latency_awareness();
unsigned long long get_generated_pkt_err();
unsigned long long get_max_connect_timeout();
unsigned long long get_unexpected_com_quit();
unsigned long long get_unexpected_packet();
unsigned long long get_aws_aurora_replicas_skipped_during_query();
unsigned long long get_backend_lagging_during_query();
unsigned long long get_backend_offline_during_query();
unsigned long long get_queries_with_max_lag_ms();
unsigned long long get_killed_connections();
unsigned long long get_killed_queries();
iface_info *MLM_find_iface_from_fd(int fd) {

@ -37,7 +37,32 @@ class SQLite3_Server {
bool debug;
#endif // DEBUG
} variables;
#ifdef TEST_AURORA
std::vector<table_def_t *> *tables_defs_aurora;
#endif // TEST_AURORA
#ifdef TEST_GALERA
std::vector<table_def_t *> *tables_defs_galera;
#endif // TEST_GALERA
#if defined(TEST_AURORA) || defined(TEST_GALERA)
void insert_into_tables_defs(std::vector<table_def_t *> *, const char *table_name, const char *table_def);
void drop_tables_defs(std::vector<table_def_t *> *tables_defs);
void check_and_build_standard_tables(SQLite3DB *db, std::vector<table_def_t *> *tables_defs);
#endif // TEST_AURORA || TEST_GALERA
public:
#ifdef TEST_AURORA
unsigned int cur_aurora_writer[3];
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);
#endif // TEST_AURORA
#ifdef TEST_GALERA
//unsigned int cur_aurora_writer[3];
unsigned int num_galera_servers[3];
unsigned int max_num_galera_servers;
pthread_mutex_t galera_mutex;
void populate_galera_table(MySQL_Session *sess);
#endif // TEST_GALERA
SQLite3_Server();
~SQLite3_Server();
char **get_variables_list();

@ -309,5 +309,15 @@ class ProxySQL_Admin {
#endif /* PROXYSQLCLICKHOUSE */
void vacuum_stats(bool);
#ifdef TEST_AURORA
void enable_aurora_testing();
#endif // TEST_AURORA
#ifdef TEST_GALERA
void enable_galera_testing();
#endif // TEST_GALERA
};
#endif /* __CLASS_PROXYSQL_ADMIN_H */

@ -690,6 +690,7 @@ __thread int mysql_thread___monitor_groupreplication_healthcheck_interval;
__thread int mysql_thread___monitor_groupreplication_healthcheck_timeout;
__thread int mysql_thread___monitor_galera_healthcheck_interval;
__thread int mysql_thread___monitor_galera_healthcheck_timeout;
__thread int mysql_thread___monitor_galera_healthcheck_max_timeout_count;
__thread int mysql_thread___monitor_query_interval;
__thread int mysql_thread___monitor_query_timeout;
__thread int mysql_thread___monitor_slave_lag_when_null;
@ -814,6 +815,7 @@ extern __thread int mysql_thread___monitor_groupreplication_healthcheck_interval
extern __thread int mysql_thread___monitor_groupreplication_healthcheck_timeout;
extern __thread int mysql_thread___monitor_galera_healthcheck_interval;
extern __thread int mysql_thread___monitor_galera_healthcheck_timeout;
extern __thread int mysql_thread___monitor_galera_healthcheck_max_timeout_count;
extern __thread int mysql_thread___monitor_query_interval;
extern __thread int mysql_thread___monitor_query_timeout;
extern __thread int mysql_thread___monitor_slave_lag_when_null;

@ -72,8 +72,9 @@ class Query_Processor_Output {
int sticky_conn;
int multiplex;
int gtid_from_hostgroup;
long long max_lag_ms;
int log;
char *comment; // #643
char *comment; // #643
std::string *new_query;
void * operator new(size_t size) {
return l_alloc(size);
@ -104,6 +105,7 @@ class Query_Processor_Output {
sticky_conn=-1;
multiplex=-1;
gtid_from_hostgroup=-1;
max_lag_ms=-1;
log=-1;
new_query=NULL;
error_msg=NULL;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1642,7 +1642,11 @@ __do_auth:
if (
((*myds)->sess->session_type == PROXYSQL_SESSION_ADMIN)
||
((*myds)->sess->session_type == PROXYSQL_SESSION_STATS)
((*myds)->sess->session_type == PROXYSQL_SESSION_STATS)
#if defined(TEST_AURORA) || defined(TEST_GALERA)
||
((*myds)->sess->session_type == PROXYSQL_SESSION_SQLITE)
#endif // TEST_AURORA || TEST_GALERA
) {
if (strcmp((const char *)user,mysql_thread___monitor_username)==0) {
proxy_scramble(reply, (*myds)->myconn->scramble_buff, mysql_thread___monitor_password);

@ -2594,6 +2594,9 @@ __get_pkts_from_client:
clock_gettime(CLOCK_THREAD_CPUTIME_ID,&begint);
}
qpo=GloQPro->process_mysql_query(this,pkt.ptr,pkt.size,&CurrentQuery);
if (qpo->max_lag_ms >= 0) {
thread->status_variables.queries_with_max_lag_ms++;
}
if (thread->variables.stats_time_query_processor) {
clock_gettime(CLOCK_THREAD_CPUTIME_ID,&endt);
thread->status_variables.query_processor_time=thread->status_variables.query_processor_time +
@ -3307,7 +3310,13 @@ handler_again:
myds->max_connect_time=thread->curtime+mysql_thread___connect_timeout_server_max*1000;
}
bool retry_conn=false;
proxy_error("Detected an offline server during query: %s, %d\n", myconn->parent->address, myconn->parent->port);
if (myconn->server_status==MYSQL_SERVER_STATUS_SHUNNED_REPLICATION_LAG) {
thread->status_variables.backend_lagging_during_query++;
proxy_error("Detected a lagging server during query: %s, %d\n", myconn->parent->address, myconn->parent->port);
} else {
thread->status_variables.backend_offline_during_query++;
proxy_error("Detected an offline server during query: %s, %d\n", myconn->parent->address, myconn->parent->port);
}
if (myds->query_retries_on_failure > 0) {
myds->query_retries_on_failure--;
if ((myds->myconn->reusable==true) && myds->myconn->IsActiveTransaction()==false && myds->myconn->MultiplexDisabled()==false) {
@ -3858,8 +3867,11 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(
(handshake_response_return == true)
&&
(
//(default_hostgroup<0 && ( session_type == PROXYSQL_SESSION_ADMIN || session_type == PROXYSQL_SESSION_STATS || session_type == PROXYSQL_SESSION_SQLITE) )
#if defined(TEST_AURORA) || defined(TEST_GALERA)
(default_hostgroup<0 && ( session_type == PROXYSQL_SESSION_ADMIN || session_type == PROXYSQL_SESSION_STATS || session_type == PROXYSQL_SESSION_SQLITE) )
#else
(default_hostgroup<0 && ( session_type == PROXYSQL_SESSION_ADMIN || session_type == PROXYSQL_SESSION_STATS) )
#endif // TEST_AURORA || TEST_GALERA
||
(default_hostgroup == 0 && session_type == PROXYSQL_SESSION_CLICKHOUSE)
||
@ -3903,8 +3915,12 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(
//if (session_type == PROXYSQL_SESSION_MYSQL || session_type == PROXYSQL_SESSION_CLICKHOUSE) {
client_authenticated=true;
switch (session_type) {
case PROXYSQL_SESSION_MYSQL:
case PROXYSQL_SESSION_SQLITE:
#if defined(TEST_AURORA) || defined(TEST_GALERA)
free_users=1;
break;
#endif // TEST_AURORA || TEST_GALERA
case PROXYSQL_SESSION_MYSQL:
if (ldap_ctx==NULL) {
free_users=GloMyAuth->increase_frontend_user_connections(client_myds->myconn->userinfo->username, &used_users);
} else {
@ -4774,6 +4790,19 @@ void MySQL_Session::handler___client_DSS_QUERY_SENT___server_DSS_NOT_INITIALIZED
MySQL_Backend * _gtid_from_backend = NULL;
char uuid[64];
uint64_t trxid = 0;
unsigned long long now_us = 0;
if (qpo->max_lag_ms >= 0) {
if (qpo->max_lag_ms > 360000) { // this is an absolute time, we convert it to relative
if (now_us == 0) {
now_us = realtime_time();
}
long long now_ms = now_us/1000;
qpo->max_lag_ms -= now_ms;
if (qpo->max_lag_ms < 0) {
qpo->max_lag_ms = -1; // time expired
}
}
}
if (session_fast_forward == false) {
if (qpo->gtid_from_hostgroup >= 0) {
_gtid_from_backend = find_backend(qpo->gtid_from_hostgroup);
@ -4795,16 +4824,16 @@ void MySQL_Session::handler___client_DSS_QUERY_SENT___server_DSS_NOT_INITIALIZED
}
}
uuid[n]='\0';
mc=thread->get_MyConn_local(mybe->hostgroup_id, this, uuid, trxid);
mc=thread->get_MyConn_local(mybe->hostgroup_id, this, uuid, trxid, -1);
} else {
mc=thread->get_MyConn_local(mybe->hostgroup_id, this, NULL, 0);
mc=thread->get_MyConn_local(mybe->hostgroup_id, this, NULL, 0, (int)qpo->max_lag_ms);
}
}
if (mc==NULL) {
if (trxid) {
mc=MyHGM->get_MyConn_from_pool(mybe->hostgroup_id, this, session_fast_forward, uuid, trxid);
mc=MyHGM->get_MyConn_from_pool(mybe->hostgroup_id, this, session_fast_forward, uuid, trxid, -1);
} else {
mc=MyHGM->get_MyConn_from_pool(mybe->hostgroup_id, this, session_fast_forward, NULL, 0);
mc=MyHGM->get_MyConn_from_pool(mybe->hostgroup_id, this, session_fast_forward, NULL, 0, (int)qpo->max_lag_ms);
}
} else {
thread->status_variables.ConnPool_get_conn_immediate++;
@ -4815,6 +4844,15 @@ void MySQL_Session::handler___client_DSS_QUERY_SENT___server_DSS_NOT_INITIALIZED
} else {
thread->status_variables.ConnPool_get_conn_failure++;
}
if (qpo->max_lag_ms >= 0) {
if (qpo->max_lag_ms <= 360000) { // this is a relative time , we convert it to absolute
if (now_us == 0) {
now_us = realtime_time();
}
long long now_ms = now_us/1000;
qpo->max_lag_ms += now_ms;
}
}
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess=%p -- server_myds=%p -- MySQL_Connection %p\n", this, mybe->server_myds, mybe->server_myds->myconn);
if (mybe->server_myds->myconn==NULL) {
// we couldn't get a connection for whatever reason, ex: no backends, or too busy

@ -245,6 +245,7 @@ static char * mysql_thread_variables_names[]= {
(char *)"monitor_groupreplication_healthcheck_timeout",
(char *)"monitor_galera_healthcheck_interval",
(char *)"monitor_galera_healthcheck_timeout",
(char *)"monitor_galera_healthcheck_max_timeout_count",
(char *)"monitor_username",
(char *)"monitor_password",
(char *)"monitor_replication_lag_use_percona_heartbeat",
@ -324,6 +325,7 @@ static char * mysql_thread_variables_names[]= {
(char *)"default_sql_mode",
(char *)"default_time_zone",
(char *)"connpoll_reset_queue_length",
(char *)"min_num_servers_lantency_awareness",
(char *)"stats_time_backend_query",
(char *)"stats_time_query_processor",
(char *)"query_cache_stores_empty_result",
@ -375,6 +377,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() {
variables.monitor_groupreplication_healthcheck_timeout=800;
variables.monitor_galera_healthcheck_interval=5000;
variables.monitor_galera_healthcheck_timeout=800;
variables.monitor_galera_healthcheck_max_timeout_count=3;
variables.monitor_query_interval=60000;
variables.monitor_query_timeout=100;
variables.monitor_slave_lag_when_null=60;
@ -445,6 +448,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() {
variables.query_digests_normalize_digest_text=false;
variables.query_digests_track_hostname=false;
variables.connpoll_reset_queue_length = 50;
variables.min_num_servers_lantency_awareness = 1000;
variables.stats_time_backend_query=false;
variables.stats_time_query_processor=false;
variables.query_cache_stores_empty_result=true;
@ -652,6 +656,7 @@ int MySQL_Threads_Handler::get_variable_int(const char *name) {
if (!strcmp(name,"monitor_groupreplication_healthcheck_timeout")) return (int)variables.monitor_groupreplication_healthcheck_timeout;
if (!strcmp(name,"monitor_galera_healthcheck_interval")) return (int)variables.monitor_galera_healthcheck_interval;
if (!strcmp(name,"monitor_galera_healthcheck_timeout")) return (int)variables.monitor_galera_healthcheck_timeout;
if (!strcmp(name,"monitor_galera_healthcheck_max_timeout_count")) return (int)variables.monitor_galera_healthcheck_max_timeout_count;
}
if (a == 'p' || a == 'P') {
if (!strcmp(name,"monitor_ping_interval")) return (int)variables.monitor_ping_interval;
@ -696,6 +701,7 @@ int MySQL_Threads_Handler::get_variable_int(const char *name) {
#ifdef IDLE_THREADS
if (!strcmp(name,"session_idle_ms")) return (int)variables.session_idle_ms;
#endif // IDLE_THREADS
if (!strcmp(name,"min_num_servers_lantency_awareness")) return variables.min_num_servers_lantency_awareness;
if (!strcmp(name,"stats_time_backend_query")) return (int)variables.stats_time_backend_query;
if (!strcmp(name,"stats_time_query_processor")) return (int)variables.stats_time_query_processor;
if (!strcmp(name,"sessions_sort")) return (int)variables.sessions_sort;
@ -781,6 +787,7 @@ int MySQL_Threads_Handler::get_variable_int(const char *name) {
if (!strcmp(name,"query_digests_normalize_digest_text")) return (int)variables.query_digests_normalize_digest_text;
if (!strcmp(name,"query_digests_track_hostname")) return (int)variables.query_digests_track_hostname;
if (!strcmp(name,"connpoll_reset_queue_length")) return (int)variables.connpoll_reset_queue_length;
if (!strcmp(name,"min_num_servers_lantency_awareness")) return (int)variables.min_num_servers_lantency_awareness;
if (!strcmp(name,"stats_time_backend_query")) return (int)variables.stats_time_backend_query;
if (!strcmp(name,"stats_time_query_processor")) return (int)variables.stats_time_query_processor;
if (!strcmp(name,"query_cache_stores_empty_result")) return (int)variables.query_cache_stores_empty_result;
@ -947,6 +954,10 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f
sprintf(intbuf,"%d",variables.monitor_galera_healthcheck_timeout);
return strdup(intbuf);
}
if (!strcasecmp(name,"monitor_galera_healthcheck_max_timeout_count")) {
sprintf(intbuf,"%d",variables.monitor_galera_healthcheck_max_timeout_count);
return strdup(intbuf);
}
if (!strcasecmp(name,"monitor_query_interval")) {
sprintf(intbuf,"%d",variables.monitor_query_interval);
return strdup(intbuf);
@ -1163,6 +1174,10 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f
sprintf(intbuf,"%d",variables.poll_timeout_on_failure);
return strdup(intbuf);
}
if (!strcasecmp(name,"min_num_servers_lantency_awareness")) {
sprintf(intbuf,"%d",variables.min_num_servers_lantency_awareness);
return strdup(intbuf);
}
if (!strcasecmp(name,"threads")) {
sprintf(intbuf,"%d", (num_threads ? num_threads : DEFAULT_NUM_THREADS));
return strdup(intbuf);
@ -1452,6 +1467,15 @@ bool MySQL_Threads_Handler::set_variable(char *name, char *value) { // this is t
return false;
}
}
if (!strcasecmp(name,"monitor_galera_healthcheck_max_timeout_count")) {
int intv=atoi(value);
if (intv >= 1 && intv <= 10) {
variables.monitor_galera_healthcheck_max_timeout_count=intv;
return true;
} else {
return false;
}
}
if (!strcasecmp(name,"monitor_query_interval")) {
int intv=atoi(value);
if (intv >= 100 && intv <= 7*24*3600*1000) {
@ -2105,6 +2129,15 @@ bool MySQL_Threads_Handler::set_variable(char *name, char *value) { // this is t
return false;
}
}
if (!strcasecmp(name,"min_num_servers_lantency_awareness")) {
int intv=atoi(value);
if (intv >= 0 && intv <= 10000) {
variables.min_num_servers_lantency_awareness=intv;
return true;
} else {
return false;
}
}
if (!strcasecmp(name,"default_charset")) {
if (vallen) {
MARIADB_CHARSET_INFO * c=proxysql_find_charset_name(value);
@ -3747,6 +3780,7 @@ void MySQL_Thread::refresh_variables() {
mysql_thread___monitor_groupreplication_healthcheck_timeout=GloMTH->get_variable_int((char *)"monitor_groupreplication_healthcheck_timeout");
mysql_thread___monitor_galera_healthcheck_interval=GloMTH->get_variable_int((char *)"monitor_galera_healthcheck_interval");
mysql_thread___monitor_galera_healthcheck_timeout=GloMTH->get_variable_int((char *)"monitor_galera_healthcheck_timeout");
mysql_thread___monitor_galera_healthcheck_max_timeout_count=GloMTH->get_variable_int((char *)"monitor_galera_healthcheck_max_timeout_count");
mysql_thread___monitor_query_interval=GloMTH->get_variable_int((char *)"monitor_query_interval");
mysql_thread___monitor_query_timeout=GloMTH->get_variable_int((char *)"monitor_query_timeout");
mysql_thread___monitor_slave_lag_when_null=GloMTH->get_variable_int((char *)"monitor_slave_lag_when_null");
@ -3792,6 +3826,7 @@ void MySQL_Thread::refresh_variables() {
mysql_thread___query_digests_lowercase=(bool)GloMTH->get_variable_int((char *)"query_digests_lowercase");
mysql_thread___query_digests_normalize_digest_text=(bool)GloMTH->get_variable_int((char *)"query_digests_normalize_digest_text");
mysql_thread___query_digests_track_hostname=(bool)GloMTH->get_variable_int((char *)"query_digests_track_hostname");
variables.min_num_servers_lantency_awareness=GloMTH->get_variable_int((char *)"min_num_servers_lantency_awareness");
variables.stats_time_backend_query=(bool)GloMTH->get_variable_int((char *)"stats_time_backend_query");
variables.stats_time_query_processor=(bool)GloMTH->get_variable_int((char *)"stats_time_query_processor");
variables.query_cache_stores_empty_result=(bool)GloMTH->get_variable_int((char *)"query_cache_stores_empty_result");
@ -3869,17 +3904,23 @@ MySQL_Thread::MySQL_Thread() {
status_variables.ConnPool_get_conn_immediate=0;
status_variables.ConnPool_get_conn_success=0;
status_variables.ConnPool_get_conn_failure=0;
status_variables.ConnPool_get_conn_latency_awareness=0;
status_variables.active_transactions=0;
status_variables.gtid_session_collected = 0;
status_variables.generated_pkt_err = 0;
status_variables.max_connect_timeout_err = 0;
status_variables.backend_lagging_during_query = 0;
status_variables.backend_offline_during_query = 0;
status_variables.queries_with_max_lag_ms = 0;
status_variables.unexpected_com_quit = 0;
status_variables.unexpected_packet = 0;
status_variables.killed_connections = 0;
status_variables.killed_queries = 0;
status_variables.aws_aurora_replicas_skipped_during_query = 0;
match_regexes=NULL;
variables.min_num_servers_lantency_awareness = 1000;
variables.stats_time_backend_query=false;
variables.stats_time_query_processor=false;
variables.query_cache_stores_empty_result=true;
@ -4343,6 +4384,12 @@ SQLite3_result * MySQL_Threads_Handler::SQL3_GlobalStatus(bool _memory) {
result->add_row(pta);
}
}
{ // ConnPool_get_conn_latency_awareness
pta[0]=(char *)"ConnPool_get_conn_latency_awareness";
sprintf(buf,"%llu",get_ConnPool_get_conn_latency_awareness());
pta[1]=buf;
result->add_row(pta);
}
{ // ConnPool_get_conn_immediate
pta[0]=(char *)"ConnPool_get_conn_immediate";
sprintf(buf,"%llu",get_ConnPool_get_conn_immediate());
@ -4373,6 +4420,24 @@ SQLite3_result * MySQL_Threads_Handler::SQL3_GlobalStatus(bool _memory) {
pta[1]=buf;
result->add_row(pta);
}
{ // backend_lagging_during_query
pta[0]=(char *)"backend_lagging_during_query";
sprintf(buf,"%llu",get_backend_lagging_during_query());
pta[1]=buf;
result->add_row(pta);
}
{ // backend_offline_during_query
pta[0]=(char *)"backend_offline_during_query";
sprintf(buf,"%llu",get_backend_offline_during_query());
pta[1]=buf;
result->add_row(pta);
}
{ // queries_with_max_lag_ms
pta[0]=(char *)"queries_with_max_lag_ms";
sprintf(buf,"%llu",get_queries_with_max_lag_ms());
pta[1]=buf;
result->add_row(pta);
}
{ // Unexpected COM_QUIT
pta[0]=(char *)"mysql_unexpected_frontend_com_quit";
sprintf(buf,"%llu",get_unexpected_com_quit());
@ -4385,6 +4450,12 @@ SQLite3_result * MySQL_Threads_Handler::SQL3_GlobalStatus(bool _memory) {
pta[1]=buf;
result->add_row(pta);
}
{ // AWS Aurora replicas skipped during query
pta[0]=(char *)"aws_aurora_replicas_skipped_during_query";
sprintf(buf,"%llu",get_aws_aurora_replicas_skipped_during_query());
pta[1]=buf;
result->add_row(pta);
}
{ // killed connections
pta[0]=(char *)"mysql_killed_backend_connections";
sprintf(buf,"%llu",get_killed_connections());
@ -5156,7 +5227,7 @@ void MySQL_Thread::Get_Memory_Stats() {
}
MySQL_Connection * MySQL_Thread::get_MyConn_local(unsigned int _hid, MySQL_Session *sess, char *gtid_uuid, uint64_t gtid_trxid) {
MySQL_Connection * MySQL_Thread::get_MyConn_local(unsigned int _hid, MySQL_Session *sess, char *gtid_uuid, uint64_t gtid_trxid, int max_lag_ms) {
unsigned int i;
unsigned int bc = 0; // best candidate
bool pcf = false; // possible candidate found
@ -5210,6 +5281,12 @@ MySQL_Connection * MySQL_Thread::get_MyConn_local(unsigned int _hid, MySQL_Sessi
} else {
// c=(MySQL_Connection *)cached_connections->remove_index_fast(i);
if (max_lag_ms >= 0) {
if (max_lag_ms < (c->parent->aws_aurora_current_lag_us / 1000)) {
status_variables.aws_aurora_replicas_skipped_during_query++;
continue;
}
}
if (pcf == false) {
bc = i;
pcf = true;
@ -5278,6 +5355,19 @@ void MySQL_Thread::return_local_connections() {
}
}
unsigned long long MySQL_Threads_Handler::get_ConnPool_get_conn_latency_awareness() {
unsigned long long q=0;
unsigned int i;
for (i=0;i<num_threads;i++) {
if (mysql_threads) {
MySQL_Thread *thr=(MySQL_Thread *)mysql_threads[i].worker;
if (thr)
q+=__sync_fetch_and_add(&thr->status_variables.ConnPool_get_conn_latency_awareness,0);
}
}
return q;
}
unsigned long long MySQL_Threads_Handler::get_ConnPool_get_conn_immediate() {
unsigned long long q=0;
unsigned int i;
@ -5330,6 +5420,45 @@ unsigned long long MySQL_Threads_Handler::get_generated_pkt_err() {
return q;
}
unsigned long long MySQL_Threads_Handler::get_backend_lagging_during_query() {
unsigned long long q=0;
unsigned int i;
for (i=0;i<num_threads;i++) {
if (mysql_threads) {
MySQL_Thread *thr=(MySQL_Thread *)mysql_threads[i].worker;
if (thr)
q+=__sync_fetch_and_add(&thr->status_variables.backend_lagging_during_query,0);
}
}
return q;
}
unsigned long long MySQL_Threads_Handler::get_backend_offline_during_query() {
unsigned long long q=0;
unsigned int i;
for (i=0;i<num_threads;i++) {
if (mysql_threads) {
MySQL_Thread *thr=(MySQL_Thread *)mysql_threads[i].worker;
if (thr)
q+=__sync_fetch_and_add(&thr->status_variables.backend_offline_during_query,0);
}
}
return q;
}
unsigned long long MySQL_Threads_Handler::get_queries_with_max_lag_ms() {
unsigned long long q=0;
unsigned int i;
for (i=0;i<num_threads;i++) {
if (mysql_threads) {
MySQL_Thread *thr=(MySQL_Thread *)mysql_threads[i].worker;
if (thr)
q+=__sync_fetch_and_add(&thr->status_variables.queries_with_max_lag_ms,0);
}
}
return q;
}
unsigned long long MySQL_Threads_Handler::get_max_connect_timeout() {
unsigned long long q=0;
unsigned int i;
@ -5369,6 +5498,19 @@ unsigned long long MySQL_Threads_Handler::get_unexpected_packet() {
return q;
}
unsigned long long MySQL_Threads_Handler::get_aws_aurora_replicas_skipped_during_query() {
unsigned long long q=0;
unsigned int i;
for (i=0;i<num_threads;i++) {
if (mysql_threads) {
MySQL_Thread *thr=(MySQL_Thread *)mysql_threads[i].worker;
if (thr)
q+=__sync_fetch_and_add(&thr->status_variables.aws_aurora_replicas_skipped_during_query,0);
}
}
return q;
}
unsigned long long MySQL_Threads_Handler::get_killed_connections() {
unsigned long long q=0;
unsigned int i;

@ -351,6 +351,15 @@ static int http_handler(void *cls, struct MHD_Connection *connection, const char
#define ADMIN_SQLITE_TABLE_RUNTIME_MYSQL_GALERA_HOSTGROUPS "CREATE TABLE runtime_mysql_galera_hostgroups (writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY , backup_writer_hostgroup INT CHECK (backup_writer_hostgroup>=0 AND backup_writer_hostgroup<>writer_hostgroup) NOT NULL , reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND backup_writer_hostgroup<>reader_hostgroup AND reader_hostgroup>0) , offline_hostgroup INT NOT NULL CHECK (offline_hostgroup<>writer_hostgroup AND offline_hostgroup<>reader_hostgroup AND backup_writer_hostgroup<>offline_hostgroup AND offline_hostgroup>=0) , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , max_writers INT NOT NULL CHECK (max_writers >= 0) DEFAULT 1 , writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1,2)) NOT NULL DEFAULT 0 , max_transactions_behind INT CHECK (max_transactions_behind>=0) NOT NULL DEFAULT 0 , comment VARCHAR , UNIQUE (reader_hostgroup) , UNIQUE (offline_hostgroup) , UNIQUE (backup_writer_hostgroup))"
// AWS Aurora
#define ADMIN_SQLITE_TABLE_MYSQL_AWS_AURORA_HOSTGROUPS_V2_1_0a "CREATE TABLE mysql_aws_aurora_hostgroups (writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY , reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND reader_hostgroup>0) , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , aurora_port INT NOT NUlL DEFAULT 3306 , endpoint_address VARCHAR NOT NULL DEFAULT '' , max_lag_ms INT NOT NULL CHECK (max_lag_ms>= 10 AND max_lag_ms <= 600000) DEFAULT 600000 , check_interval_ms INT NOT NULL CHECK (check_interval_ms >= 100 AND check_interval_ms <= 600000) DEFAULT 1000 , check_timeout_ms INT NOT NULL CHECK (check_timeout_ms >= 80 AND check_timeout_ms <= 3000) DEFAULT 800 , writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1)) NOT NULL DEFAULT 0 , new_reader_weight INT CHECK (new_reader_weight >= 0 AND new_reader_weight <=10000000) NOT NULL DEFAULT 1 , comment VARCHAR , UNIQUE (reader_hostgroup))"
#define ADMIN_SQLITE_TABLE_MYSQL_AWS_AURORA_HOSTGROUPS ADMIN_SQLITE_TABLE_MYSQL_AWS_AURORA_HOSTGROUPS_V2_1_0a
#define ADMIN_SQLITE_TABLE_RUNTIME_MYSQL_AWS_AURORA_HOSTGROUPS "CREATE TABLE runtime_mysql_aws_aurora_hostgroups (writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY , reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND reader_hostgroup>0) , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , aurora_port INT NOT NUlL DEFAULT 3306 , endpoint_address VARCHAR NOT NULL DEFAULT '' , max_lag_ms INT NOT NULL CHECK (max_lag_ms>= 10 AND max_lag_ms <= 600000) DEFAULT 600000 , check_interval_ms INT NOT NULL CHECK (check_interval_ms >= 100 AND check_interval_ms <= 600000) DEFAULT 1000 , check_timeout_ms INT NOT NULL CHECK (check_timeout_ms >= 80 AND check_timeout_ms <= 3000) DEFAULT 800 , writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1)) NOT NULL DEFAULT 0 , new_reader_weight INT CHECK (new_reader_weight >= 0 AND new_reader_weight <=10000000) NOT NULL DEFAULT 1 , comment VARCHAR , UNIQUE (reader_hostgroup))"
// Cluster solution
@ -2066,6 +2075,9 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign
bool monitor_mysql_server_galera_log=false;
bool monitor_mysql_server_aws_aurora_log=false;
bool monitor_mysql_server_aws_aurora_check_status=false;
bool stats_proxysql_servers_checksums = false;
bool stats_proxysql_servers_metrics = false;
bool stats_proxysql_servers_status = false;
@ -2128,6 +2140,8 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign
strstr(query_no_space,"runtime_mysql_group_replication_hostgroups")
||
strstr(query_no_space,"runtime_mysql_galera_hostgroups")
||
strstr(query_no_space,"runtime_mysql_aws_aurora_hostgroups")
) {
runtime_mysql_servers=true; refresh=true;
}
@ -2169,6 +2183,12 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign
if (strstr(query_no_space,"mysql_server_galera_log")) {
monitor_mysql_server_galera_log=true; refresh=true;
}
if (strstr(query_no_space,"mysql_server_aws_aurora_log")) {
monitor_mysql_server_aws_aurora_log=true; refresh=true;
}
if (strstr(query_no_space,"mysql_server_aws_aurora_check_status")) {
monitor_mysql_server_aws_aurora_check_status=true; refresh=true;
}
// if (stats_mysql_processlist || stats_mysql_connection_pool || stats_mysql_query_digest || stats_mysql_query_digest_reset) {
if (refresh==true) {
pthread_mutex_lock(&admin_mutex);
@ -2278,6 +2298,16 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign
GloMyMon->populate_monitor_mysql_server_galera_log();
}
}
if (monitor_mysql_server_aws_aurora_log) {
if (GloMyMon) {
GloMyMon->populate_monitor_mysql_server_aws_aurora_log();
}
}
if (monitor_mysql_server_aws_aurora_check_status) {
if (GloMyMon) {
GloMyMon->populate_monitor_mysql_server_aws_aurora_check_status();
}
}
pthread_mutex_unlock(&admin_mutex);
}
if (
@ -3015,6 +3045,15 @@ void admin_session_handler(MySQL_Session *sess, void *_pa, PtrSize_t *pkt) {
tablename=(char *)"MYSQL GALERA HOSTGROUPS";
SPA->admindb->execute_statement(q, &error, &cols, &affected_rows, &resultset);
}
if ((strlen(query_no_space)==strlen("CHECKSUM MEMORY MYSQL AURORA HOSTGROUPS") && !strncasecmp("CHECKSUM MEMORY GROUP MYSQL REPLICATION HOSTGROUPS", query_no_space, strlen(query_no_space)))
||
(strlen(query_no_space)==strlen("CHECKSUM MEM MYSQL AURORA HOSTGROUPS") && !strncasecmp("CHECKSUM MEM MYSQL AURORA HOSTGROUPS", query_no_space, strlen(query_no_space)))
||
(strlen(query_no_space)==strlen("CHECKSUM MYSQL AURORA HOSTGROUPS") && !strncasecmp("CHECKSUM MYSQL AURORA HOSTGROUPS", query_no_space, strlen(query_no_space)))){
char *q=(char *)"SELECT * FROM mysql_aws_aurora_hostgroups ORDER BY writer_hostgroup";
tablename=(char *)"MYSQL AURORA HOSTGROUPS";
SPA->admindb->execute_statement(q, &error, &cols, &affected_rows, &resultset);
}
if (error) {
proxy_error("Error: %s\n", error);
@ -3850,6 +3889,8 @@ bool ProxySQL_Admin::init() {
insert_into_tables_defs(tables_defs_admin,"runtime_mysql_group_replication_hostgroups", ADMIN_SQLITE_TABLE_RUNTIME_MYSQL_GROUP_REPLICATION_HOSTGROUPS);
insert_into_tables_defs(tables_defs_admin,"mysql_galera_hostgroups", ADMIN_SQLITE_TABLE_MYSQL_GALERA_HOSTGROUPS);
insert_into_tables_defs(tables_defs_admin,"runtime_mysql_galera_hostgroups", ADMIN_SQLITE_TABLE_RUNTIME_MYSQL_GALERA_HOSTGROUPS);
insert_into_tables_defs(tables_defs_admin,"mysql_aws_aurora_hostgroups", ADMIN_SQLITE_TABLE_MYSQL_AWS_AURORA_HOSTGROUPS);
insert_into_tables_defs(tables_defs_admin,"runtime_mysql_aws_aurora_hostgroups", ADMIN_SQLITE_TABLE_RUNTIME_MYSQL_AWS_AURORA_HOSTGROUPS);
insert_into_tables_defs(tables_defs_admin,"mysql_query_rules", ADMIN_SQLITE_TABLE_MYSQL_QUERY_RULES);
insert_into_tables_defs(tables_defs_admin,"mysql_query_rules_fast_routing", ADMIN_SQLITE_TABLE_MYSQL_QUERY_RULES_FAST_ROUTING);
insert_into_tables_defs(tables_defs_admin,"runtime_mysql_query_rules", ADMIN_SQLITE_TABLE_RUNTIME_MYSQL_QUERY_RULES);
@ -3875,6 +3916,7 @@ bool ProxySQL_Admin::init() {
insert_into_tables_defs(tables_defs_config,"mysql_replication_hostgroups", ADMIN_SQLITE_TABLE_MYSQL_REPLICATION_HOSTGROUPS);
insert_into_tables_defs(tables_defs_config,"mysql_group_replication_hostgroups", ADMIN_SQLITE_TABLE_MYSQL_GROUP_REPLICATION_HOSTGROUPS);
insert_into_tables_defs(tables_defs_config,"mysql_galera_hostgroups", ADMIN_SQLITE_TABLE_MYSQL_GALERA_HOSTGROUPS);
insert_into_tables_defs(tables_defs_config,"mysql_aws_aurora_hostgroups", ADMIN_SQLITE_TABLE_MYSQL_AWS_AURORA_HOSTGROUPS);
insert_into_tables_defs(tables_defs_config,"mysql_query_rules", ADMIN_SQLITE_TABLE_MYSQL_QUERY_RULES);
insert_into_tables_defs(tables_defs_config,"mysql_query_rules_fast_routing", ADMIN_SQLITE_TABLE_MYSQL_QUERY_RULES_FAST_ROUTING);
insert_into_tables_defs(tables_defs_config,"global_variables", ADMIN_SQLITE_TABLE_GLOBAL_VARIABLES);
@ -6605,6 +6647,7 @@ void ProxySQL_Admin::__insert_or_ignore_maintable_select_disktable() {
admindb->execute("INSERT OR IGNORE INTO main.mysql_replication_hostgroups SELECT * FROM disk.mysql_replication_hostgroups");
admindb->execute("INSERT OR IGNORE INTO main.mysql_group_replication_hostgroups SELECT * FROM disk.mysql_group_replication_hostgroups");
admindb->execute("INSERT OR IGNORE INTO main.mysql_galera_hostgroups SELECT * FROM disk.mysql_galera_hostgroups");
admindb->execute("INSERT OR IGNORE INTO main.mysql_aws_aurora_hostgroups SELECT * FROM disk.mysql_aws_aurora_hostgroups");
admindb->execute("INSERT OR IGNORE INTO main.mysql_users SELECT * FROM disk.mysql_users");
admindb->execute("INSERT OR IGNORE INTO main.mysql_query_rules SELECT * FROM disk.mysql_query_rules");
admindb->execute("INSERT OR IGNORE INTO main.mysql_query_rules_fast_routing SELECT * FROM disk.mysql_query_rules_fast_routing");
@ -6631,6 +6674,7 @@ void ProxySQL_Admin::__insert_or_replace_maintable_select_disktable() {
admindb->execute("INSERT OR REPLACE INTO main.mysql_replication_hostgroups SELECT * FROM disk.mysql_replication_hostgroups");
admindb->execute("INSERT OR REPLACE INTO main.mysql_group_replication_hostgroups SELECT * FROM disk.mysql_group_replication_hostgroups");
admindb->execute("INSERT OR REPLACE INTO main.mysql_galera_hostgroups SELECT * FROM disk.mysql_galera_hostgroups");
admindb->execute("INSERT OR REPLACE INTO main.mysql_aws_aurora_hostgroups SELECT * FROM disk.mysql_aws_aurora_hostgroups");
admindb->execute("INSERT OR REPLACE INTO main.mysql_users SELECT * FROM disk.mysql_users");
admindb->execute("INSERT OR REPLACE INTO main.mysql_query_rules SELECT * FROM disk.mysql_query_rules");
admindb->execute("INSERT OR REPLACE INTO main.mysql_query_rules_fast_routing SELECT * FROM disk.mysql_query_rules_fast_routing");
@ -6649,6 +6693,9 @@ void ProxySQL_Admin::__insert_or_replace_maintable_select_disktable() {
admindb->execute("INSERT OR REPLACE INTO main.mysql_ldap_mapping SELECT * FROM disk.mysql_ldap_mapping");
}
admindb->execute("PRAGMA foreign_keys = ON");
#if defined(TEST_AURORA) || defined(TEST_GALERA)
admindb->execute("DELETE FROM mysql_servers WHERE gtid_port > 0"); // temporary disable add GTID checks
#endif
}
void ProxySQL_Admin::__delete_disktable() {
@ -6678,6 +6725,7 @@ void ProxySQL_Admin::__insert_or_replace_disktable_select_maintable() {
admindb->execute("INSERT OR REPLACE INTO disk.mysql_replication_hostgroups SELECT * FROM main.mysql_replication_hostgroups");
admindb->execute("INSERT OR REPLACE INTO disk.mysql_group_replication_hostgroups SELECT * FROM main.mysql_group_replication_hostgroups");
admindb->execute("INSERT OR REPLACE INTO disk.mysql_galera_hostgroups SELECT * FROM main.mysql_galera_hostgroups");
admindb->execute("INSERT OR REPLACE INTO disk.mysql_aws_aurora_hostgroups SELECT * FROM main.mysql_aws_aurora_hostgroups");
admindb->execute("INSERT OR REPLACE INTO disk.mysql_query_rules SELECT * FROM main.mysql_query_rules");
admindb->execute("INSERT OR REPLACE INTO disk.mysql_users SELECT * FROM main.mysql_users");
admindb->execute("INSERT OR REPLACE INTO disk.mysql_query_rules_fast_routing SELECT * FROM main.mysql_query_rules_fast_routing");
@ -6765,10 +6813,12 @@ void ProxySQL_Admin::flush_mysql_servers__from_disk_to_memory() {
admindb->execute("DELETE FROM main.mysql_replication_hostgroups");
admindb->execute("DELETE FROM main.mysql_group_replication_hostgroups");
admindb->execute("DELETE FROM main.mysql_galera_hostgroups");
admindb->execute("DELETE FROM main.mysql_aws_aurora_hostgroups");
admindb->execute("INSERT INTO main.mysql_servers SELECT * FROM disk.mysql_servers");
admindb->execute("INSERT INTO main.mysql_replication_hostgroups SELECT * FROM disk.mysql_replication_hostgroups");
admindb->execute("INSERT INTO main.mysql_group_replication_hostgroups SELECT * FROM disk.mysql_group_replication_hostgroups");
admindb->execute("INSERT INTO main.mysql_galera_hostgroups SELECT * FROM disk.mysql_galera_hostgroups");
admindb->execute("INSERT INTO main.mysql_aws_aurora_hostgroups SELECT * FROM disk.mysql_aws_aurora_hostgroups");
admindb->execute("PRAGMA foreign_keys = ON");
admindb->wrunlock();
}
@ -6780,10 +6830,12 @@ void ProxySQL_Admin::flush_mysql_servers__from_memory_to_disk() {
admindb->execute("DELETE FROM disk.mysql_replication_hostgroups");
admindb->execute("DELETE FROM disk.mysql_group_replication_hostgroups");
admindb->execute("DELETE FROM disk.mysql_galera_hostgroups");
admindb->execute("DELETE FROM disk.mysql_aws_aurora_hostgroups");
admindb->execute("INSERT INTO disk.mysql_servers SELECT * FROM main.mysql_servers");
admindb->execute("INSERT INTO disk.mysql_replication_hostgroups SELECT * FROM main.mysql_replication_hostgroups");
admindb->execute("INSERT INTO disk.mysql_group_replication_hostgroups SELECT * FROM main.mysql_group_replication_hostgroups");
admindb->execute("INSERT INTO disk.mysql_galera_hostgroups SELECT * FROM main.mysql_galera_hostgroups");
admindb->execute("INSERT INTO disk.mysql_aws_aurora_hostgroups SELECT * FROM main.mysql_aws_aurora_hostgroups");
admindb->execute("PRAGMA foreign_keys = ON");
admindb->wrunlock();
}
@ -7948,6 +8000,50 @@ void ProxySQL_Admin::save_mysql_servers_runtime_to_database(bool _runtime) {
}
sqlite3_finalize(statement);
}
// dump mysql_aws_aurora_hostgroups
if (_runtime) {
query=(char *)"DELETE FROM main.runtime_mysql_aws_aurora_hostgroups";
} else {
query=(char *)"DELETE FROM main.mysql_aws_aurora_hostgroups";
}
proxy_debug(PROXY_DEBUG_ADMIN, 4, "%s\n", query);
admindb->execute(query);
resultset=MyHGM->dump_table_mysql_aws_aurora_hostgroups();
if (resultset) {
int rc;
sqlite3_stmt *statement=NULL;
sqlite3 *mydb3=admindb->get_db();
char *query=NULL;
if (_runtime) {
query=(char *)"INSERT INTO runtime_mysql_aws_aurora_hostgroups(writer_hostgroup,reader_hostgroup,active,aurora_port,endpoint_address,max_lag_ms,check_interval_ms,check_timeout_ms,writer_is_also_reader,new_reader_weight,comment) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11)";
} else {
query=(char *)"INSERT INTO mysql_aws_aurora_hostgroups(writer_hostgroup,reader_hostgroup,active,aurora_port,endpoint_address,max_lag_ms,check_interval_ms,check_timeout_ms,writer_is_also_reader,new_reader_weight,comment) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11)";
}
rc=sqlite3_prepare_v2(mydb3, query, -1, &statement, 0);
assert(rc==SQLITE_OK);
//proxy_info("New mysql_aws_aurora_hostgroups table\n");
for (std::vector<SQLite3_row *>::iterator it = resultset->rows.begin() ; it != resultset->rows.end(); ++it) {
SQLite3_row *r=*it;
rc=sqlite3_bind_int64(statement, 1, atoi(r->fields[0])); assert(rc==SQLITE_OK);
rc=sqlite3_bind_int64(statement, 2, atoi(r->fields[1])); assert(rc==SQLITE_OK);
rc=sqlite3_bind_int64(statement, 3, atoi(r->fields[2])); assert(rc==SQLITE_OK);
rc=sqlite3_bind_int64(statement, 4, atoi(r->fields[3])); assert(rc==SQLITE_OK);
rc=sqlite3_bind_text(statement, 5, r->fields[4], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK);
rc=sqlite3_bind_int64(statement, 6, atoi(r->fields[5])); assert(rc==SQLITE_OK);
rc=sqlite3_bind_int64(statement, 7, atoi(r->fields[6])); assert(rc==SQLITE_OK);
rc=sqlite3_bind_int64(statement, 8, atoi(r->fields[7])); assert(rc==SQLITE_OK);
rc=sqlite3_bind_int64(statement, 9, atoi(r->fields[8])); assert(rc==SQLITE_OK);
rc=sqlite3_bind_int64(statement, 10, atoi(r->fields[9])); assert(rc==SQLITE_OK);
rc=sqlite3_bind_text(statement, 11, r->fields[10], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK);
SAFE_SQLITE3_STEP2(statement);
rc=sqlite3_clear_bindings(statement); assert(rc==SQLITE_OK);
rc=sqlite3_reset(statement); assert(rc==SQLITE_OK);
}
sqlite3_finalize(statement);
}
if(resultset) delete resultset;
resultset=NULL;
}
@ -7978,6 +8074,7 @@ void ProxySQL_Admin::load_mysql_servers_to_runtime() {
SQLite3_result *resultset_replication=NULL;
SQLite3_result *resultset_group_replication=NULL;
SQLite3_result *resultset_galera=NULL;
SQLite3_result *resultset_aws_aurora=NULL;
char *query=(char *)"SELECT hostgroup_id,hostname,port,gtid_port,status,weight,compression,max_connections,max_replication_lag,use_ssl,max_latency_ms,comment FROM main.mysql_servers";
proxy_debug(PROXY_DEBUG_ADMIN, 4, "%s\n", query);
admindb->execute_statement(query, &error , &cols , &affected_rows , &resultset);
@ -8072,6 +8169,36 @@ void ProxySQL_Admin::load_mysql_servers_to_runtime() {
MyHGM->set_incoming_galera_hostgroups(resultset_galera);
}
// support for AWS Aurora, table mysql_aws_aurora_hostgroups
// look for invalid combinations
query=(char *)"SELECT a.* FROM mysql_aws_aurora_hostgroups a JOIN mysql_aws_aurora_hostgroups b ON a.writer_hostgroup=b.reader_hostgroup WHERE b.reader_hostgroup";
proxy_debug(PROXY_DEBUG_ADMIN, 4, "%s\n", query);
admindb->execute_statement(query, &error , &cols , &affected_rows , &resultset);
if (error) {
proxy_error("Error on %s : %s\n", query, error);
} else {
for (std::vector<SQLite3_row *>::iterator it = resultset->rows.begin() ; it != resultset->rows.end(); ++it) {
SQLite3_row *r=*it;
proxy_error("Incompatible entry in mysql_aws_aurora_hostgroups will be ignored : ( %s , %s , %s , %s )\n", r->fields[0], r->fields[1], r->fields[2], r->fields[3]);
}
}
if (resultset) delete resultset;
resultset=NULL;
#ifdef AURORA_TEST // temporary enabled only for testing purpose
query=(char *)"SELECT a.* FROM mysql_aws_aurora_hostgroups a LEFT JOIN mysql_aws_aurora_hostgroups b ON (a.writer_hostgroup=b.reader_hostgroup) WHERE b.reader_hostgroup IS NULL";
#else
query=(char *)"SELECT a.* FROM mysql_aws_aurora_hostgroups a WHERE 1=0";
#endif
proxy_debug(PROXY_DEBUG_ADMIN, 4, "%s\n", query);
admindb->execute_statement(query, &error , &cols , &affected_rows , &resultset_aws_aurora);
if (error) {
proxy_error("Error on %s : %s\n", query, error);
} else {
// Pass the resultset to MyHGM
MyHGM->set_incoming_aws_aurora_hostgroups(resultset_aws_aurora);
}
// commit all the changes
MyHGM->commit();
@ -8090,6 +8217,10 @@ void ProxySQL_Admin::load_mysql_servers_to_runtime() {
//delete resultset_galera; // do not delete, resultset is stored in MyHGM
resultset_galera=NULL;
}
if (resultset_aws_aurora) {
//delete resultset_aws_aurora; // do not delete, resultset is stored in MyHGM
resultset_aws_aurora=NULL;
}
}
@ -8817,6 +8948,49 @@ int ProxySQL_Admin::Read_MySQL_Servers_from_configfile() {
free(query);
rows++;
}
}
if (root.exists("mysql_aws_aurora_hostgroups")==true) {
const Setting &mysql_aws_aurora_hostgroups = root["mysql_aws_aurora_hostgroups"];
int count = mysql_aws_aurora_hostgroups.getLength();
char *q=(char *)"INSERT OR REPLACE INTO mysql_aws_aurora_hostgroups (writer_hostgroup, reader_hostgroup, active, aurora_port, endpoint_address, max_lag_ms, check_interval_ms, check_timeout_ms, writer_is_also_reader, new_reader_weight, comment) VALUES (%d, %d, %d, %d, '%s', %d, %d, %d, %d, %d, '%s')";
for (i=0; i< count; i++) {
const Setting &line = mysql_aws_aurora_hostgroups[i];
int writer_hostgroup;
int reader_hostgroup;
int active=1; // default
int aurora_port;
int max_lag_ms;
int check_interval_ms;
int check_timeout_ms;
int writer_is_also_reader;
int new_reader_weight;
std::string comment="";
std::string endpoint_address="";
if (line.lookupValue("writer_hostgroup", writer_hostgroup)==false) continue;
if (line.lookupValue("reader_hostgroup", reader_hostgroup)==false) continue;
if (line.lookupValue("aurora_port", aurora_port)==false) aurora_port=3306;
if (line.lookupValue("max_lag_ms", max_lag_ms)==false) max_lag_ms=600000;
if (line.lookupValue("check_interval_ms", check_interval_ms)==false) check_interval_ms=1000;
if (line.lookupValue("check_timeout_ms", check_timeout_ms)==false) check_timeout_ms=1000;
if (line.lookupValue("writer_is_also_reader", writer_is_also_reader)==false) writer_is_also_reader=0;
if (line.lookupValue("new_reader_weight", new_reader_weight)==false) new_reader_weight=0;
line.lookupValue("comment", comment);
line.lookupValue("endpoint_address", comment);
char *o1=strdup(comment.c_str());
char *o=escape_string_single_quotes(o1, false);
char *p1=strdup(endpoint_address.c_str());
char *p=escape_string_single_quotes(p1, false);
char *query=(char *)malloc(strlen(q)+strlen(o)+strlen(p)+256); // 128 vs sizeof(int)*8
sprintf(query,q, writer_hostgroup, reader_hostgroup, active, aurora_port, p, max_lag_ms, check_interval_ms, check_timeout_ms, writer_is_also_reader, new_reader_weight, o);
//fprintf(stderr, "%s\n", query);
admindb->execute(query);
if (o!=o1) free(o);
free(o1);
if (p!=p1) free(p);
free(p1);
free(query);
rows++;
}
}
admindb->execute("PRAGMA foreign_keys = ON");
return rows;
@ -9747,3 +9921,104 @@ void ProxySQL_Admin::stats___mysql_prepared_statements_info() {
statsdb->execute("COMMIT");
delete resultset;
}
#ifdef TEST_GALERA
void ProxySQL_Admin::enable_galera_testing() {
proxy_info("Admin is enabling Galera Testing using SQLite3 Server and HGs from 2271 and 2290\n");
sqlite3_stmt *statement=NULL;
sqlite3 *mydb3=admindb->get_db();
unsigned int num_galera_servers = GloSQLite3Server->num_galera_servers[0];
int rc;
mysql_servers_wrlock();
admindb->execute("DELETE FROM mysql_servers WHERE hostgroup_id BETWEEN 2271 AND 2300");
char *query=(char *)"INSERT INTO mysql_servers (hostgroup_id,hostname,use_ssl,comment) VALUES (?1, ?2, ?3, ?4)";
rc=sqlite3_prepare_v2(mydb3, query, -1, &statement, 0);
assert(rc==SQLITE_OK);
for (unsigned int j=1; j<4; j++) {
proxy_info("Admin is enabling Galera Testing using SQLite3 Server and writer_HG %d\n" , 2260+j*10+1);
for (unsigned int i=0; i<num_galera_servers; i++) {
string serverid = "";
serverid = "127.1." + std::to_string(j) + "." + std::to_string(i+11);
string sessionid= "";
sessionid = "node_" + serverid;
rc=sqlite3_bind_int64(statement, 1, 2260+j*10+1 ); assert(rc==SQLITE_OK);
rc=sqlite3_bind_text(statement, 2, serverid.c_str(), -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK);
rc=sqlite3_bind_int64(statement, 3, 0); assert(rc==SQLITE_OK);
rc=sqlite3_bind_text(statement, 4, sessionid.c_str(), -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK);
SAFE_SQLITE3_STEP2(statement);
rc=sqlite3_clear_bindings(statement); assert(rc==SQLITE_OK);
rc=sqlite3_reset(statement); assert(rc==SQLITE_OK);
}
}
sqlite3_finalize(statement);
admindb->execute("INSERT INTO mysql_galera_hostgroups (writer_hostgroup, backup_writer_hostgroup, reader_hostgroup, offline_hostgroup, active, max_writers, writer_is_also_reader, max_transactions_behind, comment) VALUES (2271, 2272, 2273, 2274, 0, 1, 1, 0, 'Automated Galera Testing Cluster 1')");
admindb->execute("INSERT INTO mysql_galera_hostgroups (writer_hostgroup, backup_writer_hostgroup, reader_hostgroup, offline_hostgroup, active, max_writers, writer_is_also_reader, max_transactions_behind, comment) VALUES (2281, 2282, 2283, 2284, 0, 1, 1, 0, 'Automated Galera Testing Cluster 2')");
admindb->execute("INSERT INTO mysql_galera_hostgroups (writer_hostgroup, backup_writer_hostgroup, reader_hostgroup, offline_hostgroup, active, max_writers, writer_is_also_reader, max_transactions_behind, comment) VALUES (2291, 2292, 2293, 2294, 0, 1, 1, 0, 'Automated Galera Testing Cluster 3')");
admindb->execute("UPDATE mysql_galera_hostgroups SET active=1");
//admindb->execute("update mysql_servers set max_replication_lag=20");
load_mysql_servers_to_runtime();
mysql_servers_wrunlock();
admindb->execute("UPDATE global_variables SET variable_value=200 WHERE variable_name='mysql-monitor_ping_interval'");
admindb->execute("UPDATE global_variables SET variable_value=3000 WHERE variable_name='mysql-monitor_ping_timeout'");
admindb->execute("UPDATE global_variables SET variable_value=200 WHERE variable_name='mysql-monitor_replication_lag_interval'");
admindb->execute("UPDATE global_variables SET variable_value=3000 WHERE variable_name='mysql-monitor_replication_lag_timeout'");
admindb->execute("UPDATE global_variables SET variable_value='percona.heartbeat' WHERE variable_name='mysql-monitor_replication_lag_use_percona_heartbeat'");
load_mysql_variables_to_runtime();
admindb->execute("INSERT INTO mysql_users (username,password,default_hostgroup) VALUES ('galera1','pass1',2271), ('galera2','pass2',2281), ('galera','pass3',2291)");
init_users();
}
#endif // TEST_GALERA
#ifdef TEST_AURORA
void ProxySQL_Admin::enable_aurora_testing() {
proxy_info("Admin is enabling AWS Aurora Testing using SQLite3 Server and HGs from 1271 to 1276\n");
sqlite3_stmt *statement=NULL;
sqlite3 *mydb3=admindb->get_db();
unsigned int num_aurora_servers = GloSQLite3Server->num_aurora_servers[0];
int rc;
mysql_servers_wrlock();
admindb->execute("DELETE FROM mysql_servers WHERE hostgroup_id BETWEEN 1271 AND 1276");
char *query=(char *)"INSERT INTO mysql_servers (hostgroup_id,hostname,use_ssl,comment) VALUES (?1, ?2, ?3, ?4)";
rc=sqlite3_prepare_v2(mydb3, query, -1, &statement, 0);
assert(rc==SQLITE_OK);
for (unsigned int j=1; j<4; j++) {
proxy_info("Admin is enabling AWS Aurora Testing using SQLite3 Server and HGs 127%d and 127%d\n" , j*2-1 , j*2);
for (unsigned int i=0; i<num_aurora_servers; i++) {
string serverid = "";
if (j==1) {
serverid = "host." + std::to_string(j) + "." + std::to_string(i+11) + ".aws-test.com";
} else {
serverid = "127.0." + std::to_string(j) + "." + std::to_string(i+11);
}
string sessionid= "";
sessionid = "b80ef4b4-" + serverid + "-aa01";
rc=sqlite3_bind_int64(statement, 1, 1270+j*2 ); assert(rc==SQLITE_OK);
rc=sqlite3_bind_text(statement, 2, serverid.c_str(), -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK);
rc=sqlite3_bind_int64(statement, 3, 0); assert(rc==SQLITE_OK);
rc=sqlite3_bind_text(statement, 4, sessionid.c_str(), -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK);
SAFE_SQLITE3_STEP2(statement);
rc=sqlite3_clear_bindings(statement); assert(rc==SQLITE_OK);
rc=sqlite3_reset(statement); assert(rc==SQLITE_OK);
}
}
sqlite3_finalize(statement);
admindb->execute("INSERT INTO mysql_aws_aurora_hostgroups (writer_hostgroup, reader_hostgroup, active, endpoint_address, max_lag_ms, check_interval_ms, check_timeout_ms, writer_is_also_reader, new_reader_weight, comment) VALUES (1271, 1272, 1, '.aws-test.com', 25, 120, 90, 1, 1, 'Automated Aurora Testing Cluster 1')");
admindb->execute("INSERT INTO mysql_aws_aurora_hostgroups (writer_hostgroup, reader_hostgroup, active, max_lag_ms, check_interval_ms, check_timeout_ms, writer_is_also_reader, new_reader_weight, comment) VALUES (1273, 1274, 1, 25, 120, 90, 0, 1, 'Automated Aurora Testing Cluster 2')");
admindb->execute("INSERT INTO mysql_aws_aurora_hostgroups (writer_hostgroup, reader_hostgroup, active, max_lag_ms, check_interval_ms, check_timeout_ms, writer_is_also_reader, new_reader_weight, comment) VALUES (1275, 1276, 1, 25, 120, 90, 0, 2, 'Automated Aurora Testing Cluster 3')");
admindb->execute("UPDATE mysql_aws_aurora_hostgroups SET active=1");
//admindb->execute("update mysql_servers set max_replication_lag=20");
load_mysql_servers_to_runtime();
mysql_servers_wrunlock();
//admindb->execute("UPDATE global_variables SET variable_value=3000 WHERE variable_name='mysql-monitor_ping_interval'");
//admindb->execute("UPDATE global_variables SET variable_value=1500 WHERE variable_name='mysql-monitor_ping_timeout'");
//admindb->execute("UPDATE global_variables SET variable_value=3000 WHERE variable_name='mysql-monitor_replication_lag_interval'");
//admindb->execute("UPDATE global_variables SET variable_value=1500 WHERE variable_name='mysql-monitor_replication_lag_timeout'");
admindb->execute("UPDATE global_variables SET variable_value=200 WHERE variable_name='mysql-monitor_ping_interval'");
admindb->execute("UPDATE global_variables SET variable_value=3000 WHERE variable_name='mysql-monitor_ping_timeout'");
admindb->execute("UPDATE global_variables SET variable_value=200 WHERE variable_name='mysql-monitor_replication_lag_interval'");
admindb->execute("UPDATE global_variables SET variable_value=3000 WHERE variable_name='mysql-monitor_replication_lag_timeout'");
admindb->execute("UPDATE global_variables SET variable_value='percona.heartbeat' WHERE variable_name='mysql-monitor_replication_lag_use_percona_heartbeat'");
load_mysql_variables_to_runtime();
admindb->execute("INSERT INTO mysql_users (username,password,default_hostgroup) VALUES ('aurora1','pass1',1271), ('aurora2','pass2',1273), ('aurora3','pass3',1275)");
init_users();
}
#endif // TEST_AURORA

@ -1946,6 +1946,12 @@ bool Query_Processor::query_parser_first_comment(Query_Processor_Output *qpo, ch
qpo->mirror_hostgroup=t;
}
}
if (!strcasecmp(key,"max_lag_ms")) {
if (c >= '0' && c <= '9') { // it is a digit
int t=atoi(value);
qpo->max_lag_ms = t;
}
}
}
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "Variables in comment %s , key=%s , value=%s\n", token, key, value);

@ -118,8 +118,8 @@ typedef struct _ifaces_desc_t {
char **mysql_ifaces;
} ifaces_desc_t;
#define MAX_IFACES 8
#define MAX_SQLITE3SERVER_LISTENERS 16
#define MAX_IFACES 128
#define MAX_SQLITE3SERVER_LISTENERS 128
class ifaces_desc {
public:
@ -246,6 +246,38 @@ void SQLite3_Server_session_handler(MySQL_Session *sess, void *_pa, PtrSize_t *p
memcpy(query,(char *)pkt->ptr+sizeof(mysql_hdr)+1,query_length-1);
query[query_length-1]=0;
#if defined(TEST_AURORA) || defined(TEST_GALERA)
if (sess->client_myds->proxy_addr.addr == NULL) {
struct sockaddr addr;
socklen_t addr_len=sizeof(struct sockaddr);
memset(&addr,0,addr_len);
int rc;
rc=getsockname(sess->client_myds->fd, &addr, &addr_len);
if (rc==0) {
char buf[512];
switch (addr.sa_family) {
case AF_INET: {
struct sockaddr_in *ipv4 = (struct sockaddr_in *)&addr;
inet_ntop(addr.sa_family, &ipv4->sin_addr, buf, INET_ADDRSTRLEN);
sess->client_myds->proxy_addr.addr = strdup(buf);
}
break;
case AF_INET6: {
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&addr;
inet_ntop(addr.sa_family, &ipv6->sin6_addr, buf, INET6_ADDRSTRLEN);
sess->client_myds->proxy_addr.addr = strdup(buf);
}
break;
default:
sess->client_myds->proxy_addr.addr = strdup("unknown");
break;
}
} else {
sess->client_myds->proxy_addr.addr = strdup("unknown");
}
}
#endif // TEST_AURORA || TEST_GALERA
char *query_no_space=(char *)l_alloc(query_length);
memcpy(query_no_space,query,query_length);
@ -260,7 +292,13 @@ void SQLite3_Server_session_handler(MySQL_Session *sess, void *_pa, PtrSize_t *p
if (query_no_space_length==SELECT_VERSION_COMMENT_LEN) {
if (!strncasecmp(SELECT_VERSION_COMMENT, query_no_space, query_no_space_length)) {
l_free(query_length,query);
query=l_strdup("SELECT '(ProxySQL Admin Module)'");
#if defined(TEST_AURORA) || defined(TEST_GALERA)
char *a = (char *)"SELECT '(ProxySQL Automated Test Server) - %s'";
query = (char *)malloc(strlen(a)+strlen(sess->client_myds->proxy_addr.addr));
sprintf(query,a,sess->client_myds->proxy_addr.addr);
#else
query=l_strdup("SELECT '(ProxySQL SQLite3 Server)'");
#endif // TEST_AURORA || TEST_GALERA
query_length=strlen(query)+1;
goto __run_query;
}
@ -436,8 +474,61 @@ __end_show_commands:
__run_query:
if (run_query) {
#if defined(TEST_AURORA) || defined(TEST_GALERA)
if (strncasecmp("SELECT",query_no_space,6)==0) {
#ifdef TEST_AURORA
if (strstr(query_no_space,(char *)"REPLICA_HOST_STATUS")) {
pthread_mutex_lock(&GloSQLite3Server->aurora_mutex);
GloSQLite3Server->populate_aws_aurora_table(sess);
}
#endif // TEST_AURORA
#ifdef TEST_GALERA
if (strstr(query_no_space,(char *)"HOST_STATUS_GALERA")) {
pthread_mutex_lock(&GloSQLite3Server->galera_mutex);
GloSQLite3Server->populate_galera_table(sess);
}
#endif // TEST_GALERA
if (strstr(query_no_space,(char *)"Seconds_Behind_Master")) {
free(query);
char *a = (char *)"SELECT %d as Seconds_Behind_Master";
query = (char *)malloc(strlen(a)+4);
sprintf(query,a,rand()%30+10);
}
}
#endif // TEST_AURORA || TEST_GALERA
SQLite3_Session *sqlite_sess = (SQLite3_Session *)sess->thread->gen_args;
sqlite_sess->sessdb->execute_statement(query, &error , &cols , &affected_rows , &resultset);
#if defined(TEST_AURORA) || defined(TEST_GALERA)
if (strncasecmp("SELECT",query_no_space,6)==0) {
#ifdef TEST_AURORA
if (strstr(query_no_space,(char *)"REPLICA_HOST_STATUS")) {
pthread_mutex_unlock(&GloSQLite3Server->aurora_mutex);
if (rand() % 100 == 0) {
// randomly add some latency on 1% of the traffic
sleep(2);
}
}
#endif // TEST_AURORA
#ifdef TEST_GALERA
if (strstr(query_no_space,(char *)"HOST_STATUS_GALERA")) {
pthread_mutex_unlock(&GloSQLite3Server->galera_mutex);
if (resultset->rows_count == 0) {
PROXY_TRACE();
}
if (rand() % 20 == 0) {
// randomly add some latency on 5% of the traffic
sleep(2);
}
}
#endif // TEST_GALERA
if (strstr(query_no_space,(char *)"Seconds_Behind_Master")) {
if (rand() % 10 == 0) {
// randomly add some latency on 10% of the traffic
sleep(2);
}
}
}
#endif // TEST_AURORA || TEST_GALERA
sess->SQLite3_to_MySQL(resultset, error, affected_rows, &sess->client_myds->myprot);
delete resultset;
}
@ -639,11 +730,21 @@ __end_while_pool:
#else
#define DEB ""
#endif /* DEBUG */
#define PROXYSQL_SQLITE3_SERVER_VERSION "0.7.0625" DEB
#define PROXYSQL_SQLITE3_SERVER_VERSION "1.9.0218" DEB
SQLite3_Server::~SQLite3_Server() {
delete sessdb;
sessdb = NULL;
#ifdef TEST_GALERA
drop_tables_defs(tables_defs_galera);
delete tables_defs_galera;
#endif // TEST_GALERA
#ifdef TEST_AURORA
drop_tables_defs(tables_defs_aurora);
delete tables_defs_aurora;
#endif // TEST_AURORA
};
SQLite3_Server::SQLite3_Server() {
@ -664,10 +765,198 @@ SQLite3_Server::SQLite3_Server() {
sessdb = new SQLite3DB();
sessdb->open((char *)"file:mem_sqlitedb?mode=memory&cache=shared", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX);
variables.mysql_ifaces=strdup("127.0.0.1:6030");
variables.read_only=false;
#if defined(TEST_AURORA) || defined(TEST_GALERA)
string s = "";
#ifdef TEST_AURORA
pthread_mutex_init(&aurora_mutex,NULL);
unsigned int nas = time(NULL);
nas = nas % 3; // range
nas += 5; // min
max_num_aurora_servers = 10; // hypothetical maximum number of nodes
for (unsigned int j=1; j<4; j++) {
cur_aurora_writer[j-1] = 0;
num_aurora_servers[j-1] = nas;
for (unsigned int i=11; i<max_num_aurora_servers+11 ; i++) {
s += "127.0." + std::to_string(j) + "." + std::to_string(i) + ":3306";
if ( j!=3 || (j==3 && i<max_num_aurora_servers+11-1) ) {
s += ";";
}
}
}
#endif // TEST_AURORA
#if defined(TEST_AURORA) && defined(TEST_GALERA)
s += ";";
#endif // TEST_AURORA || TEST_GALERA
#ifdef TEST_GALERA
pthread_mutex_init(&galera_mutex,NULL);
unsigned int ngs = time(NULL);
ngs = ngs % 3; // range
ngs += 5; // min
max_num_galera_servers = 10; // hypothetical maximum number of nodes
for (unsigned int j=1; j<4; j++) {
//cur_aurora_writer[j-1] = 0;
num_galera_servers[j-1] = ngs;
for (unsigned int i=11; i<max_num_galera_servers+11 ; i++) {
s += "127.1." + std::to_string(j) + "." + std::to_string(i) + ":3306";
if ( j!=3 || (j==3 && i<max_num_galera_servers+11-1) ) {
s += ";";
}
}
}
#endif // TEST_GALERA
variables.mysql_ifaces=strdup(s.c_str());
#else
variables.mysql_ifaces=strdup("127.0.0.1:6030");
#endif // TEST_AURORA || TEST_GALERA
};
#ifdef TEST_GALERA
void SQLite3_Server::populate_galera_table(MySQL_Session *sess) {
// this function needs to be called with lock on mutex galera_mutex already acquired
sessdb->execute("BEGIN TRANSACTION");
char *error=NULL;
int cols=0;
int affected_rows=0;
SQLite3_result *resultset=NULL;
sqlite3 *mydb3=sessdb->get_db();
string myip = string(sess->client_myds->proxy_addr.addr);
string clu_id_s = myip.substr(6,1);
unsigned int cluster_id = atoi(clu_id_s.c_str());
cluster_id--;
int hg_id = 2270+(cluster_id*10)+1;
char buf[1024];
sprintf(buf, (char *)"SELECT * FROM HOST_STATUS_GALERA WHERE hostgroup_id = %d LIMIT 1", hg_id);
sessdb->execute_statement(buf, &error , &cols , &affected_rows , &resultset);
if (resultset->rows_count==0) {
//sessdb->execute("DELETE FROM HOST_STATUS_GALERA");
sqlite3_stmt *statement=NULL;
int rc;
char *query=(char *)"INSERT INTO HOST_STATUS_GALERA VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)";
rc=sqlite3_prepare_v2(mydb3, query, -1, &statement, 0);
assert(rc==SQLITE_OK);
for (unsigned int i=0; i<num_galera_servers[cluster_id]; i++) {
string serverid = "";
serverid = "127.1." + std::to_string(cluster_id+1) + "." + std::to_string(i+11);
// fprintf(stderr,"%d , %s:3306 \n", hg_id , serverid.c_str());
rc=sqlite3_bind_int64(statement, 1, hg_id); assert(rc==SQLITE_OK);
rc=sqlite3_bind_text(statement, 2, serverid.c_str(), -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK);
rc=sqlite3_bind_int64(statement, 3, 3306); assert(rc==SQLITE_OK);
rc=sqlite3_bind_int64(statement, 4, 4); assert(rc==SQLITE_OK); // wsrep_local_state
rc=sqlite3_bind_int64(statement, 5, 0); assert(rc==SQLITE_OK); // read_only
rc=sqlite3_bind_int64(statement, 6, 0); assert(rc==SQLITE_OK); // wsrep_local_recv_queue
rc=sqlite3_bind_int64(statement, 7, 0); assert(rc==SQLITE_OK); // wsrep_desync
rc=sqlite3_bind_text(statement, 8, (char *)"NONE", -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // wsrep_reject_queries
rc=sqlite3_bind_int64(statement, 9, 0); assert(rc==SQLITE_OK); // wsrep_sst_donor_rejects_queries
rc=sqlite3_bind_text(statement, 10, (char *)"Primary", -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // wsrep_cluster_status
SAFE_SQLITE3_STEP2(statement);
rc=sqlite3_clear_bindings(statement); assert(rc==SQLITE_OK);
rc=sqlite3_reset(statement); assert(rc==SQLITE_OK);
}
sqlite3_finalize(statement);
}
sessdb->execute("COMMIT");
}
#endif // TEST_GALERA
#ifdef TEST_AURORA
void SQLite3_Server::populate_aws_aurora_table(MySQL_Session *sess) {
// this function needs to be called with lock on mutex aurora_mutex already acquired
sessdb->execute("DELETE FROM REPLICA_HOST_STATUS");
sqlite3_stmt *statement=NULL;
sqlite3 *mydb3=sessdb->get_db();
int rc;
char *query=(char *)"INSERT INTO REPLICA_HOST_STATUS VALUES (?1, ?2, ?3, ?4, ?5)";
rc=sqlite3_prepare_v2(mydb3, query, -1, &statement, 0);
assert(rc==SQLITE_OK);
time_t __timer;
char lut[30];
struct tm __tm_info;
time(&__timer);
localtime_r(&__timer, &__tm_info);
strftime(lut, 25, "%Y-%m-%d %H:%M:%S", &__tm_info);
string myip = string(sess->client_myds->proxy_addr.addr);
string clu_id_s = myip.substr(6,1);
unsigned int cluster_id = atoi(clu_id_s.c_str());
cluster_id--;
//if (rand() % 200 == 0) {
if (rand() % 20000 == 0) {
// simulate a failover
cur_aurora_writer[cluster_id] = rand() % num_aurora_servers[cluster_id];
proxy_info("Simulating a failover for AWS Aurora cluster %d , HGs (%d:%d)\n", cluster_id, 1270 + cluster_id*2+1 , 1270 + cluster_id*2+2);
}
for (unsigned int i=0; i<num_aurora_servers[cluster_id]; i++) {
string serverid = "";
if (cluster_id==0) {
serverid = "host." + std::to_string(cluster_id+1) + "." + std::to_string(i+11);
} else {
serverid = "127.0." + std::to_string(cluster_id+1) + "." + std::to_string(i+11);
}
string sessionid= "";
float lag_ms = 0;
if (i==cur_aurora_writer[cluster_id]) {
sessionid = "MASTER_SESSION_ID";
} else {
sessionid = "b80ef4b4-" + serverid + "-aa01";
int lag_ms_i = rand();
lag_ms_i %= 2000;
lag_ms = lag_ms_i;
lag_ms /= 100;
lag_ms += 10;
}
int cpu_i = rand() % 10000;
float cpu = cpu_i;
cpu /= 100;
rc=sqlite3_bind_text(statement, 1, serverid.c_str(), -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK);
rc=sqlite3_bind_text(statement, 2, sessionid.c_str(), -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK);
rc=sqlite3_bind_double(statement, 3, cpu); assert(rc==SQLITE_OK);
rc=sqlite3_bind_text(statement, 4, lut, -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK);
rc=sqlite3_bind_double(statement, 5, lag_ms); assert(rc==SQLITE_OK);
SAFE_SQLITE3_STEP2(statement);
rc=sqlite3_clear_bindings(statement); assert(rc==SQLITE_OK);
rc=sqlite3_reset(statement); assert(rc==SQLITE_OK);
}
sqlite3_finalize(statement);
}
#endif // TEST_AURORA
#if defined(TEST_AURORA) || defined(TEST_GALERA)
void SQLite3_Server::insert_into_tables_defs(std::vector<table_def_t *> *tables_defs, const char *table_name, const char *table_def) {
table_def_t *td = new table_def_t;
td->table_name=strdup(table_name);
td->table_def=strdup(table_def);
tables_defs->push_back(td);
};
void SQLite3_Server::check_and_build_standard_tables(SQLite3DB *db, std::vector<table_def_t *> *tables_defs) {
table_def_t *td;
db->execute("PRAGMA foreign_keys = OFF");
for (std::vector<table_def_t *>::iterator it=tables_defs->begin(); it!=tables_defs->end(); ++it) {
td=*it;
db->check_and_build_table(td->table_name, td->table_def);
}
db->execute("PRAGMA foreign_keys = ON");
};
void SQLite3_Server::drop_tables_defs(std::vector<table_def_t *> *tables_defs) {
table_def_t *td;
while (!tables_defs->empty()) {
td=tables_defs->back();
free(td->table_name);
td->table_name=NULL;
free(td->table_def);
td->table_def=NULL;
tables_defs->pop_back();
delete td;
}
};
#endif // TEST_AURORA || TEST_GALERA
void SQLite3_Server::wrlock() {
pthread_rwlock_wrlock(&rwlock);
};
@ -684,6 +973,23 @@ void SQLite3_Server::print_version() {
bool SQLite3_Server::init() {
cpu_timer cpt;
#ifdef TEST_AURORA
tables_defs_aurora = new std::vector<table_def_t *>;
insert_into_tables_defs(tables_defs_aurora,
(const char *)"REPLICA_HOST_STATUS",
(const char *)"CREATE TABLE REPLICA_HOST_STATUS (SERVER_ID VARCHAR NOT NULL, SESSION_ID VARCHAR NOT NULL, CPU REAL NOT NULL, LAST_UPDATE_TIMESTAMP VARCHAR NOT NULL, REPLICA_LAG_IN_MILLISECONDS REAL NOT NULL)");
check_and_build_standard_tables(sessdb, tables_defs_aurora);
GloAdmin->enable_aurora_testing();
#endif // TEST_AURORA
#ifdef TEST_GALERA
tables_defs_galera = new std::vector<table_def_t *>;
insert_into_tables_defs(tables_defs_galera,
(const char *)"HOST_STATUS_GALERA",
(const char *)"CREATE TABLE HOST_STATUS_GALERA (hostgroup_id INT NOT NULL , hostname VARCHAR NOT NULL , port INT NOT NULL , wsrep_local_state VARCHAR , read_only VARCHAR , wsrep_local_recv_queue VARCHAR , wsrep_desync VARCHAR , wsrep_reject_queries VARCHAR , wsrep_sst_donor_rejects_queries VARCHAR , wsrep_cluster_status VARCHAR , PRIMARY KEY (hostgroup_id, hostname, port))");
check_and_build_standard_tables(sessdb, tables_defs_galera);
GloAdmin->enable_galera_testing();
#endif // TEST_GALERA
child_func[0]=child_mysql;
main_shutdown=0;
main_poll_nfds=0;

@ -132,5 +132,5 @@ $(LIBPROXYSQLAR):
default: $(EXECUTABLE)
clean:
rm -f *.pid $(ODIR)/*.o *~ core $(EXECUTABLE)
rm -f *.pid $(ODIR)/*.o *~ core perf.data* heaptrack.proxysql.* $(EXECUTABLE)

@ -1384,6 +1384,8 @@ bool ProxySQL_daemonize_phase3() {
int main(int argc, const char * argv[]) {
{
MYSQL *my = mysql_init(NULL);
mysql_close(my);
// cpu_timer t;
ProxySQL_Main_init();
#ifdef DEBUG
@ -1672,7 +1674,9 @@ finish:
#ifdef RUNNING_ON_VALGRIND
if (RUNNING_ON_VALGRIND==0) {
dlclose(__mysql_ldap_auth);
if (__mysql_ldap_auth) {
dlclose(__mysql_ldap_auth);
}
}
#endif
return 0;

Loading…
Cancel
Save