Improve debugging when unable to reach hostgroup

When we generate an error "Max connect timeout reached while reaching hostgroup" for the client, now the error log is more verbose.
pull/3467/head
René Cannaò 5 years ago
parent b8b840fe30
commit 6c7503f85f

@ -540,7 +540,7 @@ class MySQL_HostGroups_Manager {
void drop_all_idle_connections();
int get_multiple_idle_connections(int, unsigned long long, MySQL_Connection **, int);
SQLite3_result * SQL3_Connection_Pool(bool _reset);
SQLite3_result * SQL3_Connection_Pool(bool _reset, int *hid = NULL);
SQLite3_result * SQL3_Free_Connections();
void push_MyConn_to_pool(MySQL_Connection *, bool _lock=true);

@ -277,6 +277,7 @@ class MySQL_Session
void unable_to_parse_set_statement(bool *);
bool has_any_backend();
void detected_broken_connection(const char *file, unsigned int line, const char *func, const char *action, MySQL_Connection *myconn, int myerr, const char *message, bool verbose=false);
void generate_status_one_hostgroup(int hid, std::string& s);
};
#define KILL_QUERY 1

@ -2779,6 +2779,7 @@ MySrvC *MyHGC::get_random_MySrvC(char * gtid_uuid, uint64_t gtid_trxid, int max_
MySrvC *mysrvcCandidates_static[32];
MySrvC **mysrvcCandidates = mysrvcCandidates_static;
unsigned int num_candidates = 0;
bool max_connections_reached = false;
if (l>32) {
mysrvcCandidates = (MySrvC **)malloc(sizeof(MySrvC *)*l);
}
@ -2814,6 +2815,8 @@ MySrvC *MyHGC::get_random_MySrvC(char * gtid_uuid, uint64_t gtid_trxid, int max_
}
}
}
} else {
max_connections_reached = true;
}
} else {
if (mysrvc->status==MYSQL_SERVER_STATUS_SHUNNED) {
@ -2911,7 +2914,9 @@ MySrvC *MyHGC::get_random_MySrvC(char * gtid_uuid, uint64_t gtid_trxid, int max_
}
if (t - last_hg_log > 1) { // log this at most once per second to avoid spamming the logs
last_hg_log = time(NULL);
proxy_error("Hostgroup %u has no servers available! Checking servers shunned for more than %u second%s\n", hid, max_wait_sec, max_wait_sec == 1 ? "" : "s");
proxy_error("Hostgroup %u has no servers available%s! Checking servers shunned for more than %u second%s\n", hid,
(max_connections_reached ? " or max_connections reached for all servers" : ""),
max_wait_sec, max_wait_sec == 1 ? "" : "s");
}
for (j=0; j<l; j++) {
mysrvc=mysrvs->idx(j);
@ -3776,7 +3781,7 @@ void MySQL_HostGroups_Manager::p_update_connection_pool() {
wrunlock();
}
SQLite3_result * MySQL_HostGroups_Manager::SQL3_Connection_Pool(bool _reset) {
SQLite3_result * MySQL_HostGroups_Manager::SQL3_Connection_Pool(bool _reset, int *hid) {
const int colnum=14;
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 4, "Dumping Connection Pool\n");
SQLite3_result *result=new SQLite3_result(colnum);
@ -3800,17 +3805,23 @@ SQLite3_result * MySQL_HostGroups_Manager::SQL3_Connection_Pool(bool _reset) {
MyHGC *myhgc=(MyHGC *)MyHostGroups->index(i);
for (j=0; j<(int)myhgc->mysrvs->cnt(); j++) {
MySrvC *mysrvc=(MySrvC *)myhgc->mysrvs->servers->index(j);
if (mysrvc->status!=MYSQL_SERVER_STATUS_ONLINE) {
proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 5, "Server %s:%d is not online\n", mysrvc->address, mysrvc->port);
//__sync_fetch_and_sub(&status.server_connections_connected, mysrvc->ConnectionsFree->conns->len);
mysrvc->ConnectionsFree->drop_all_connections();
}
// drop idle connections if beyond max_connection
while (mysrvc->ConnectionsFree->conns_length() && mysrvc->ConnectionsUsed->conns_length()+mysrvc->ConnectionsFree->conns_length() > mysrvc->max_connections) {
//MySQL_Connection *conn=(MySQL_Connection *)mysrvc->ConnectionsFree->conns->remove_index_fast(0);
MySQL_Connection *conn=mysrvc->ConnectionsFree->remove(0);
delete conn;
//__sync_fetch_and_sub(&status.server_connections_connected, 1);
if (hid == NULL) {
if (mysrvc->status!=MYSQL_SERVER_STATUS_ONLINE) {
proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 5, "Server %s:%d is not online\n", mysrvc->address, mysrvc->port);
//__sync_fetch_and_sub(&status.server_connections_connected, mysrvc->ConnectionsFree->conns->len);
mysrvc->ConnectionsFree->drop_all_connections();
}
// drop idle connections if beyond max_connection
while (mysrvc->ConnectionsFree->conns_length() && mysrvc->ConnectionsUsed->conns_length()+mysrvc->ConnectionsFree->conns_length() > mysrvc->max_connections) {
//MySQL_Connection *conn=(MySQL_Connection *)mysrvc->ConnectionsFree->conns->remove_index_fast(0);
MySQL_Connection *conn=mysrvc->ConnectionsFree->remove(0);
delete conn;
//__sync_fetch_and_sub(&status.server_connections_connected, 1);
}
} else {
if (*hid != (int)myhgc->hid) {
continue;
}
}
char buf[1024];
char **pta=(char **)malloc(sizeof(char *)*colnum);

@ -2564,6 +2564,9 @@ bool MySQL_Session::handler_again___status_CONNECTING_SERVER(int *_rc) {
}
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,9001,(char *)"HY000",buf, true);
RequestEnd(mybe->server_myds);
std::string errmsg;
generate_status_one_hostgroup(current_hostgroup, errmsg);
proxy_error("%s . HG status: %s\n", buf, errmsg.c_str());
//enum session_status st;
while (previous_status.size()) {
previous_status.top();
@ -7095,3 +7098,23 @@ void MySQL_Session::detected_broken_connection(const char *file, unsigned int li
proxy_error_inline(file, line, func, "Detected a broken connection while %s on (%d,%s,%d,%lu) , user %s , last_used %llums ago : %d, %s\n", action, myconn->parent->myhgc->hid, myconn->parent->address, myconn->parent->port, myconn->get_mysql_thread_id(), myconn->userinfo->username, last_used, myerr, msg);
}
}
void MySQL_Session::generate_status_one_hostgroup(int hid, std::string& s) {
SQLite3_result *resultset = MyHGM->SQL3_Connection_Pool(false, &hid);
json j_res;
if (resultset->rows_count) {
for (std::vector<SQLite3_row *>::iterator it = resultset->rows.begin() ; it != resultset->rows.end(); ++it) {
SQLite3_row *r=*it;
json j; // one json for each row
for (int i=0; i<resultset->columns; i++) {
// using the format j["name"] == "value"
j[resultset->column_definition[i]->name] = ( r->fields[i] ? r->fields[i] : "(null)" );
}
j_res.push_back(j); // the row json is added to the final json
}
} else {
j_res=json::array();
}
s = j_res.dump();
delete resultset;
}

Loading…
Cancel
Save