diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index 1f39d8e25..259cea2e3 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -247,17 +247,19 @@ bool MySQL_HostGroups_Manager::commit() { SQLite3_result *resultset=NULL; char *query=NULL; wrlock(); - query=(char *)"SELECT mem_pointer FROM mysql_servers t1 LEFT OUTER JOIN mysql_servers_incoming t2 ON (t1.hostgroup_id=t2.hostgroup_id AND t1.hostname=t2.hostname AND t1.port=t2.port) WHERE t2.hostgroup_id IS NULL"; + query=(char *)"SELECT mem_pointer, t1.hostgroup_id, t1.hostname, t1.port FROM mysql_servers t1 LEFT OUTER JOIN mysql_servers_incoming t2 ON (t1.hostgroup_id=t2.hostgroup_id AND t1.hostname=t2.hostname AND t1.port=t2.port) WHERE t2.hostgroup_id IS NULL"; mydb->execute_statement(query, &error , &cols , &affected_rows , &resultset); if (error) { proxy_error("Error on %s : %s\n", query, error); } else { -// FIXME: this part is for debugging only, needs to be removed/cleaned -// for (std::vector::iterator it = resultset->rows.begin() ; it != resultset->rows.end(); ++it) { -// SQLite3_row *r=*it; -// long long ptr=atoll(r->fields[0]); -// fprintf(stderr,"%lld\n", ptr); -// } + for (std::vector::iterator it = resultset->rows.begin() ; it != resultset->rows.end(); ++it) { + SQLite3_row *r=*it; + long long ptr=atoll(r->fields[0]); + proxy_error("Removed server at address %lld, hostgroup %s, address %s port %s. Setting status OFFLINE HARD and immediately dropping all free connections. Used connections will be dropped when trying to use them\n", ptr, r->fields[1], r->fields[2], r->fields[3]); + MySrvC *mysrvc=(MySrvC *)ptr; + mysrvc->status=MYSQL_SERVER_STATUS_OFFLINE_HARD; + mysrvc->ConnectionsFree->drop_all_connections(); + } } if (resultset) { delete resultset; resultset=NULL; } diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 76dbe02a3..4d604815d 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -635,6 +635,25 @@ handler_again: } else { if (rc==-1) { // the query failed + if (myconn->parent->status==MYSQL_SERVER_STATUS_OFFLINE_HARD) { + // the query failed because the server is offline hard + if (mysql_thread___connect_timeout_server_max) { + 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 ((myds->myconn->reusable==true) && myds->myconn->IsActiveTransaction()==false) { + retry_conn=true; + } + myds->destroy_MySQL_Connection_From_Pool(); + myds->fd=0; + if (retry_conn) { + myds->DSS=STATE_NOT_INITIALIZED; + previous_status.push(PROCESSING_QUERY); + NEXT_IMMEDIATE(CONNECTING_SERVER); + } + return -1; + } int myerr=mysql_errno(myconn->mysql); if (myerr > 2000) { bool retry_conn=false; diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index a8fd15a74..4fb79f1ca 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -605,6 +605,8 @@ int MySQL_Connection::async_query(short event, char *stmt, unsigned long length) PROXY_TRACE(); assert(mysql); assert(ret_mysql); + if (parent->status==MYSQL_SERVER_STATUS_OFFLINE_HARD) + return -1; switch (async_state_machine) { case ASYNC_QUERY_END: return 0;