Check monitor permissions when reconnecting to server
Previously, the permissions would only be checked at monitor start. Now, the permissions are checked if [Auth Error] is on or server was reconnected.
This commit is contained in:
@ -298,24 +298,38 @@ void MariaDBMonitor::update_server(MariaDBServer& server)
|
|||||||
bool in_maintenance = server.is_in_maintenance();
|
bool in_maintenance = server.is_in_maintenance();
|
||||||
if (!in_maintenance)
|
if (!in_maintenance)
|
||||||
{
|
{
|
||||||
mxs_connect_result_t rval = mon_ping_or_connect_to_db(m_monitor, mon_srv);
|
mxs_connect_result_t conn_status = mon_ping_or_connect_to_db(m_monitor, mon_srv);
|
||||||
|
|
||||||
MYSQL* conn = mon_srv->con; // mon_ping_or_connect_to_db() may have reallocated the MYSQL struct.
|
MYSQL* conn = mon_srv->con; // mon_ping_or_connect_to_db() may have reallocated the MYSQL struct.
|
||||||
if (mon_connection_is_ok(rval))
|
|
||||||
{
|
|
||||||
server.clear_status(SERVER_AUTH_ERROR);
|
|
||||||
server.set_status(SERVER_RUNNING);
|
|
||||||
|
|
||||||
if (rval == MONITOR_CONN_NEWCONN_OK)
|
if (mon_connection_is_ok(conn_status))
|
||||||
|
{
|
||||||
|
server.set_status(SERVER_RUNNING);
|
||||||
|
if (conn_status == MONITOR_CONN_NEWCONN_OK)
|
||||||
{
|
{
|
||||||
server.update_server_info();
|
// Is a new connection or a reconnection. Check server version.
|
||||||
|
server.update_server_version();
|
||||||
}
|
}
|
||||||
if (should_update_disk_space_status(mon_srv))
|
|
||||||
|
if (server.m_version != MariaDBServer::version::UNKNOWN)
|
||||||
{
|
{
|
||||||
update_disk_space_status(mon_srv);
|
// Check permissions if permissions failed last time or if this is a new connection.
|
||||||
|
if (server.had_status(SERVER_AUTH_ERROR) || conn_status == MONITOR_CONN_NEWCONN_OK)
|
||||||
|
{
|
||||||
|
server.check_permissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If permissions are ok, continue.
|
||||||
|
if (!server.has_status(SERVER_AUTH_ERROR))
|
||||||
|
{
|
||||||
|
if (should_update_disk_space_status(mon_srv))
|
||||||
|
{
|
||||||
|
update_disk_space_status(mon_srv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query MariaDBServer specific data
|
||||||
|
server.monitor_server();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Query MariaDBServer specific data
|
|
||||||
server.monitor_server();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -332,7 +346,7 @@ void MariaDBMonitor::update_server(MariaDBServer& server)
|
|||||||
* iteration. */
|
* iteration. */
|
||||||
if (mon_srv->mon_prev_status & (SERVER_RUNNING | SERVER_MAINT))
|
if (mon_srv->mon_prev_status & (SERVER_RUNNING | SERVER_MAINT))
|
||||||
{
|
{
|
||||||
mon_log_connect_error(mon_srv, rval);
|
mon_log_connect_error(mon_srv, conn_status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -354,16 +368,6 @@ void MariaDBMonitor::pre_loop()
|
|||||||
check_maxscale_schema_replication();
|
check_maxscale_schema_replication();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check monitor permissions. Failure won't cause the monitor to stop. Afterwards, close connections so
|
|
||||||
* that update_server() reconnects and checks server version. TODO: check permissions when checking
|
|
||||||
* server version. */
|
|
||||||
check_monitor_permissions(m_monitor, "SHOW SLAVE STATUS");
|
|
||||||
for (auto iter = m_servers.begin(); iter != m_servers.end(); iter++)
|
|
||||||
{
|
|
||||||
mysql_close((*iter)->m_server_base->con);
|
|
||||||
(*iter)->m_server_base->con = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log_no_master = true;
|
m_log_no_master = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -449,6 +449,16 @@ bool MariaDBServer::is_relay_server() const
|
|||||||
(SERVER_RUNNING | SERVER_MASTER | SERVER_SLAVE);
|
(SERVER_RUNNING | SERVER_MASTER | SERVER_SLAVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MariaDBServer::has_status(uint64_t bits) const
|
||||||
|
{
|
||||||
|
return (m_server_base->pending_status & bits) == bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MariaDBServer::had_status(uint64_t bits) const
|
||||||
|
{
|
||||||
|
return (m_server_base->mon_prev_status & bits) == bits;
|
||||||
|
}
|
||||||
|
|
||||||
bool MariaDBServer::is_read_only() const
|
bool MariaDBServer::is_read_only() const
|
||||||
{
|
{
|
||||||
return m_read_only;
|
return m_read_only;
|
||||||
@ -803,7 +813,7 @@ bool MariaDBServer::update_slave_status(string* errmsg_out)
|
|||||||
* Update information which changes rarely. This method should be called after (re)connecting to a backend.
|
* Update information which changes rarely. This method should be called after (re)connecting to a backend.
|
||||||
* Calling this every monitoring loop is overkill.
|
* Calling this every monitoring loop is overkill.
|
||||||
*/
|
*/
|
||||||
void MariaDBServer::update_server_info()
|
void MariaDBServer::update_server_version()
|
||||||
{
|
{
|
||||||
m_version = version::UNKNOWN;
|
m_version = version::UNKNOWN;
|
||||||
auto conn = m_server_base->con;
|
auto conn = m_server_base->con;
|
||||||
@ -842,6 +852,38 @@ void MariaDBServer::update_server_info()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks monitor permissions on the server. Sets/clears the SERVER_AUTH_ERROR bit.
|
||||||
|
*/
|
||||||
|
void MariaDBServer::check_permissions()
|
||||||
|
{
|
||||||
|
MYSQL* conn = m_server_base->con;
|
||||||
|
// Test with a typical query to make sure the monitor has sufficient permissions.
|
||||||
|
const char* query = "SHOW SLAVE STATUS;";
|
||||||
|
if (mxs_mysql_query(conn, query) != 0)
|
||||||
|
{
|
||||||
|
/* In theory, this could be due to other errors as well, but that is quite unlikely since the
|
||||||
|
* connection was just checked. The end result is in any case that the server is not updated,
|
||||||
|
* and that this test is retried next round. */
|
||||||
|
set_status(SERVER_AUTH_ERROR);
|
||||||
|
// Only print error if last round was ok.
|
||||||
|
if (!had_status(SERVER_AUTH_ERROR))
|
||||||
|
{
|
||||||
|
MXS_WARNING("Query '%s' to server '%s' failed when checking monitor permissions: '%s'. ",
|
||||||
|
query, name(), mysql_error(conn));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clear_status(SERVER_AUTH_ERROR);
|
||||||
|
MYSQL_RES* result = mysql_store_result(conn);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
mysql_free_result(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MariaDBServer::clear_status(uint64_t bits)
|
void MariaDBServer::clear_status(uint64_t bits)
|
||||||
{
|
{
|
||||||
monitor_clear_pending_status(m_server_base, bits);
|
monitor_clear_pending_status(m_server_base, bits);
|
||||||
|
|||||||
@ -151,7 +151,8 @@ public:
|
|||||||
MariaDBServer(MXS_MONITORED_SERVER* monitored_server, int config_index);
|
MariaDBServer(MXS_MONITORED_SERVER* monitored_server, int config_index);
|
||||||
|
|
||||||
void monitor_server();
|
void monitor_server();
|
||||||
void update_server_info();
|
void update_server_version();
|
||||||
|
void check_permissions();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate how many events are left in the relay log.
|
* Calculate how many events are left in the relay log.
|
||||||
@ -261,6 +262,22 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool is_relay_server() const;
|
bool is_relay_server() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if server has the given bits on in 'pending_status'.
|
||||||
|
*
|
||||||
|
* @param bits Bits to check
|
||||||
|
* @return True if all given bits are on
|
||||||
|
*/
|
||||||
|
bool has_status(uint64_t bits) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if server has the given bits on in 'mon_prev_status'.
|
||||||
|
*
|
||||||
|
* @param bits Bits to check
|
||||||
|
* @return True if all given bits are on
|
||||||
|
*/
|
||||||
|
bool had_status(uint64_t bits) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Getter for m_read_only.
|
* Getter for m_read_only.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user