MXS-2276 Expose lower level mon_ping_or_connect_to_db

The functionality is useful also when you do not have a
MXS_MONITORED_SERVER instance.
This commit is contained in:
Johan Wikman
2019-01-21 16:45:29 +02:00
parent 5ebd237a4f
commit 0fe5b0bec9
2 changed files with 49 additions and 27 deletions

View File

@ -317,7 +317,30 @@ void monitor_check_maintenance_requests(Monitor* monitor);
bool mon_status_changed(MXS_MONITORED_SERVER* mon_srv); bool mon_status_changed(MXS_MONITORED_SERVER* mon_srv);
bool mon_print_fail_status(MXS_MONITORED_SERVER* mon_srv); bool mon_print_fail_status(MXS_MONITORED_SERVER* mon_srv);
/**
* Ping or connect to a database. If connection does not exist or ping fails, a new connection
* is created. This will always leave a valid database handle in @c *ppCon, allowing the user
* to call MySQL C API functions to find out the reason of the failure.
*
* @param mon A monitor.
* @param pServer A server.
* @param ppCon Address of pointer to a MYSQL instance. The instance should either be
* valid or NULL.
* @return Connection status.
*/
mxs_connect_result_t mon_ping_or_connect_to_db(const Monitor& mon, SERVER& server, MYSQL** ppCon);
/**
* Ping or connect to a database. If connection does not exist or ping fails, a new connection is created.
* This will always leave a valid database handle in the database->con pointer, allowing the user to call
* MySQL C API functions to find out the reason of the failure.
*
* @param mon Monitor
* @param database Monitored database
* @return Connection status.
*/
mxs_connect_result_t mon_ping_or_connect_to_db(Monitor* mon, MXS_MONITORED_SERVER* database); mxs_connect_result_t mon_ping_or_connect_to_db(Monitor* mon, MXS_MONITORED_SERVER* database);
bool mon_connection_is_ok(mxs_connect_result_t connect_result); bool mon_connection_is_ok(mxs_connect_result_t connect_result);
void mon_log_connect_error(MXS_MONITORED_SERVER* database, mxs_connect_result_t rval); void mon_log_connect_error(MXS_MONITORED_SERVER* database, mxs_connect_result_t rval);
const char* mon_get_event_name(mxs_monitor_event_t event); const char* mon_get_event_name(mxs_monitor_event_t event);

View File

@ -1375,55 +1375,45 @@ int monitor_launch_script(Monitor* mon, MXS_MONITORED_SERVER* ptr, const char* s
return rv; return rv;
} }
/** mxs_connect_result_t mon_ping_or_connect_to_db(const Monitor& mon, SERVER& server, MYSQL** ppCon)
* Ping or connect to a database. If connection does not exist or ping fails, a new connection is created.
* This will always leave a valid database handle in the database->con pointer, allowing the user to call
* MySQL C API functions to find out the reason of the failure.
*
* @param mon Monitor
* @param database Monitored database
* @return Connection status.
*/
mxs_connect_result_t mon_ping_or_connect_to_db(Monitor* mon, MXS_MONITORED_SERVER* database)
{ {
if (database->con) if (*ppCon)
{ {
/** Return if the connection is OK */ /** Return if the connection is OK */
if (mysql_ping(database->con) == 0) if (mysql_ping(*ppCon) == 0)
{ {
return MONITOR_CONN_EXISTING_OK; return MONITOR_CONN_EXISTING_OK;
} }
/** Otherwise close the handle. */ /** Otherwise close the handle. */
mysql_close(database->con); mysql_close(*ppCon);
} }
mxs_connect_result_t conn_result = MONITOR_CONN_REFUSED; mxs_connect_result_t conn_result = MONITOR_CONN_REFUSED;
if ((database->con = mysql_init(NULL))) if ((*ppCon = mysql_init(NULL)))
{ {
string uname = mon->user; string uname = mon.user;
string passwd = mon->password; string passwd = mon.password;
Server* server = static_cast<Server*>(database->server); // Clean this up later. const Server& s = static_cast<const Server&>(server); // Clean this up later.
string server_specific_monuser = server->monitor_user(); string server_specific_monuser = s.monitor_user();
if (!server_specific_monuser.empty()) if (!server_specific_monuser.empty())
{ {
uname = server_specific_monuser; uname = server_specific_monuser;
passwd = server->monitor_password(); passwd = s.monitor_password();
} }
char* dpwd = decrypt_password(passwd.c_str()); char* dpwd = decrypt_password(passwd.c_str());
mysql_optionsv(database->con, MYSQL_OPT_CONNECT_TIMEOUT, (void*) &mon->connect_timeout); mysql_optionsv(*ppCon, MYSQL_OPT_CONNECT_TIMEOUT, (void*) &mon.connect_timeout);
mysql_optionsv(database->con, MYSQL_OPT_READ_TIMEOUT, (void*) &mon->read_timeout); mysql_optionsv(*ppCon, MYSQL_OPT_READ_TIMEOUT, (void*) &mon.read_timeout);
mysql_optionsv(database->con, MYSQL_OPT_WRITE_TIMEOUT, (void*) &mon->write_timeout); mysql_optionsv(*ppCon, MYSQL_OPT_WRITE_TIMEOUT, (void*) &mon.write_timeout);
mysql_optionsv(database->con, MYSQL_PLUGIN_DIR, get_connector_plugindir()); mysql_optionsv(*ppCon, MYSQL_PLUGIN_DIR, get_connector_plugindir());
time_t start = 0; time_t start = 0;
time_t end = 0; time_t end = 0;
for (int i = 0; i < mon->connect_attempts; i++) for (int i = 0; i < mon.connect_attempts; i++)
{ {
start = time(NULL); start = time(NULL);
bool result = (mxs_mysql_real_connect(database->con, database->server, uname.c_str(), dpwd) != bool result = (mxs_mysql_real_connect(*ppCon, &server, uname.c_str(), dpwd) != NULL);
NULL);
end = time(NULL); end = time(NULL);
if (result) if (result)
@ -1433,7 +1423,7 @@ mxs_connect_result_t mon_ping_or_connect_to_db(Monitor* mon, MXS_MONITORED_SERVE
} }
} }
if (conn_result == MONITOR_CONN_REFUSED && (int)difftime(end, start) >= mon->connect_timeout) if (conn_result == MONITOR_CONN_REFUSED && (int)difftime(end, start) >= mon.connect_timeout)
{ {
conn_result = MONITOR_CONN_TIMEOUT; conn_result = MONITOR_CONN_TIMEOUT;
} }
@ -1443,6 +1433,15 @@ mxs_connect_result_t mon_ping_or_connect_to_db(Monitor* mon, MXS_MONITORED_SERVE
return conn_result; return conn_result;
} }
mxs_connect_result_t mon_ping_or_connect_to_db(Monitor* mon, MXS_MONITORED_SERVER* database)
{
mxb_assert(mon);
mxb_assert(database);
mxb_assert(database->server);
return mon_ping_or_connect_to_db(*mon, *database->server, &database->con);
}
/** /**
* Is the return value one of the 'OK' values. * Is the return value one of the 'OK' values.
* *