Merge branch '2.2' into develop
This commit is contained in:
commit
289f4990d6
@ -139,7 +139,7 @@ bool MariaDBMonitor::manual_rejoin(SERVER* rejoin_server, json_t** output)
|
||||
{
|
||||
ServerArray joinable_server;
|
||||
joinable_server.push_back(slave_cand);
|
||||
if (do_rejoin(joinable_server) == 1)
|
||||
if (do_rejoin(joinable_server, output) == 1)
|
||||
{
|
||||
rval = true;
|
||||
MXS_NOTICE("Rejoin performed.");
|
||||
@ -298,9 +298,10 @@ bool MariaDBMonitor::switchover_start_slave(MariaDBServer* old_master, MariaDBSe
|
||||
* Usually the list is created by get_joinable_servers().
|
||||
*
|
||||
* @param joinable_servers Which servers to rejoin
|
||||
* @param output Error output. Can be null.
|
||||
* @return The number of servers successfully rejoined
|
||||
*/
|
||||
uint32_t MariaDBMonitor::do_rejoin(const ServerArray& joinable_servers)
|
||||
uint32_t MariaDBMonitor::do_rejoin(const ServerArray& joinable_servers, json_t** output)
|
||||
{
|
||||
SERVER* master_server = m_master->server_base->server;
|
||||
const char* master_name = master_server->unique_name;
|
||||
@ -312,23 +313,30 @@ uint32_t MariaDBMonitor::do_rejoin(const ServerArray& joinable_servers)
|
||||
{
|
||||
MariaDBServer* joinable = *iter;
|
||||
const char* name = joinable->name();
|
||||
bool op_success;
|
||||
|
||||
if (joinable->n_slaves_configured == 0)
|
||||
if (!m_demote_sql_file.empty() && !joinable->run_sql_from_file(m_demote_sql_file, output))
|
||||
{
|
||||
MXS_NOTICE("Directing standalone server '%s' to replicate from '%s'.", name, master_name);
|
||||
op_success = joinable->join_cluster(change_cmd);
|
||||
PRINT_MXS_JSON_ERROR(output, "%s execution failed when attempting to rejoin server '%s'.",
|
||||
CN_DEMOTION_SQL_FILE, joinable->name());
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_NOTICE("Server '%s' is replicating from a server other than '%s', "
|
||||
"redirecting it to '%s'.", name, master_name, master_name);
|
||||
op_success = joinable->redirect_one_slave(change_cmd);
|
||||
}
|
||||
bool op_success;
|
||||
if (joinable->n_slaves_configured == 0)
|
||||
{
|
||||
MXS_NOTICE("Directing standalone server '%s' to replicate from '%s'.", name, master_name);
|
||||
op_success = joinable->join_cluster(change_cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_NOTICE("Server '%s' is replicating from a server other than '%s', "
|
||||
"redirecting it to '%s'.", name, master_name, master_name);
|
||||
op_success = joinable->redirect_one_slave(change_cmd);
|
||||
}
|
||||
|
||||
if (op_success)
|
||||
{
|
||||
servers_joined++;
|
||||
if (op_success)
|
||||
{
|
||||
servers_joined++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -818,6 +826,13 @@ bool MariaDBMonitor::switchover_demote_master(MariaDBServer* current_master, jso
|
||||
PRINT_MXS_JSON_ERROR(err_out, GTID_ERROR);
|
||||
}
|
||||
}
|
||||
else if (!m_demote_sql_file.empty() && !current_master->run_sql_from_file(m_demote_sql_file, err_out))
|
||||
{
|
||||
PRINT_MXS_JSON_ERROR(err_out, "%s execution failed when demoting server '%s'.",
|
||||
CN_DEMOTION_SQL_FILE, current_master->name());
|
||||
success = false;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@ -1000,12 +1015,23 @@ bool MariaDBMonitor::promote_new_master(MariaDBServer* new_master, json_t** err_
|
||||
PRINT_MXS_JSON_ERROR(err_out, "Promotion failed: '%s'. Query: '%s'.",
|
||||
mysql_error(new_master_conn), query);
|
||||
}
|
||||
// If the previous master was a slave to an external master, start the equivalent slave connection on
|
||||
// the new master. Success of replication is not checked.
|
||||
else if (m_external_master_port != PORT_UNKNOWN && !start_external_replication(new_master, err_out))
|
||||
else
|
||||
{
|
||||
success = false;
|
||||
// Promotion commands ran successfully, run promotion sql script file before external replication.
|
||||
if (!m_promote_sql_file.empty() && !new_master->run_sql_from_file(m_promote_sql_file, err_out))
|
||||
{
|
||||
PRINT_MXS_JSON_ERROR(err_out, "%s execution failed when promoting server '%s'.",
|
||||
CN_PROMOTION_SQL_FILE, new_master->name());
|
||||
success = false;
|
||||
}
|
||||
// If the previous master was a slave to an external master, start the equivalent slave connection on
|
||||
// the new master. Success of replication is not checked.
|
||||
else if (m_external_master_port != PORT_UNKNOWN && !start_external_replication(new_master, err_out))
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -34,11 +34,15 @@ static void monitorMain(void *);
|
||||
|
||||
// Config parameter names
|
||||
const char * const CN_AUTO_FAILOVER = "auto_failover";
|
||||
const char * const CN_PROMOTION_SQL_FILE = "promotion_sql_file";
|
||||
const char * const CN_DEMOTION_SQL_FILE = "demotion_sql_file";
|
||||
|
||||
static const char CN_AUTO_REJOIN[] = "auto_rejoin";
|
||||
static const char CN_FAILCOUNT[] = "failcount";
|
||||
static const char CN_NO_PROMOTE_SERVERS[] = "servers_no_promotion";
|
||||
static const char CN_FAILOVER_TIMEOUT[] = "failover_timeout";
|
||||
static const char CN_SWITCHOVER_TIMEOUT[] = "switchover_timeout";
|
||||
|
||||
// Parameters for master failure verification and timeout
|
||||
static const char CN_VERIFY_MASTER_FAILURE[] = "verify_master_failure";
|
||||
static const char CN_MASTER_FAILURE_TIMEOUT[] = "master_failure_timeout";
|
||||
@ -200,6 +204,8 @@ bool MariaDBMonitor::load_config_params(const MXS_CONFIG_PARAMETER* params)
|
||||
m_auto_rejoin = config_get_bool(params, CN_AUTO_REJOIN);
|
||||
m_verify_master_failure = config_get_bool(params, CN_VERIFY_MASTER_FAILURE);
|
||||
m_master_failure_timeout = config_get_integer(params, CN_MASTER_FAILURE_TIMEOUT);
|
||||
m_promote_sql_file = config_get_string(params, CN_PROMOTION_SQL_FILE);
|
||||
m_demote_sql_file = config_get_string(params, CN_DEMOTION_SQL_FILE);
|
||||
|
||||
m_excluded_servers.clear();
|
||||
MXS_MONITORED_SERVER** excluded_array = NULL;
|
||||
@ -211,6 +217,10 @@ bool MariaDBMonitor::load_config_params(const MXS_CONFIG_PARAMETER* params)
|
||||
MXS_FREE(excluded_array);
|
||||
|
||||
bool settings_ok = true;
|
||||
if (!check_sql_files())
|
||||
{
|
||||
settings_ok = false;
|
||||
}
|
||||
if (!set_replication_credentials(params))
|
||||
{
|
||||
MXS_ERROR("Both '%s' and '%s' must be defined", CN_REPLICATION_USER, CN_REPLICATION_PASSWORD);
|
||||
@ -577,7 +587,7 @@ void MariaDBMonitor::handle_auto_rejoin()
|
||||
ServerArray joinable_servers;
|
||||
if (get_joinable_servers(&joinable_servers))
|
||||
{
|
||||
uint32_t joins = do_rejoin(joinable_servers);
|
||||
uint32_t joins = do_rejoin(joinable_servers, NULL);
|
||||
if (joins > 0)
|
||||
{
|
||||
MXS_NOTICE("%d server(s) redirected or rejoined the cluster.", joins);
|
||||
@ -879,6 +889,30 @@ void MariaDBMonitor::load_journal()
|
||||
m_master = master_output ? get_server_info(master_output) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check sql text file parameters. A parameter should either be empty or a valid file which can be opened.
|
||||
*
|
||||
* @return True if no errors occurred when opening the files
|
||||
*/
|
||||
bool MariaDBMonitor::check_sql_files()
|
||||
{
|
||||
const char ERRMSG[] = "%s ('%s') does not exist or cannot be accessed for reading: '%s'.";
|
||||
|
||||
bool rval = true;
|
||||
if (!m_promote_sql_file.empty() && access(m_promote_sql_file.c_str(), R_OK) != 0)
|
||||
{
|
||||
rval = false;
|
||||
MXS_ERROR(ERRMSG, CN_PROMOTION_SQL_FILE, m_promote_sql_file.c_str(), mxs_strerror(errno));
|
||||
}
|
||||
|
||||
if (!m_demote_sql_file.empty() && access(m_demote_sql_file.c_str(), R_OK) != 0)
|
||||
{
|
||||
rval = false;
|
||||
MXS_ERROR(ERRMSG, CN_DEMOTION_SQL_FILE, m_demote_sql_file.c_str(), mxs_strerror(errno));
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the monitor instance and return the instance data. This function creates a thread to
|
||||
* execute the monitoring. Use stopMonitor() to stop the thread.
|
||||
@ -1146,6 +1180,8 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{CN_MASTER_FAILURE_TIMEOUT, MXS_MODULE_PARAM_COUNT, "10"},
|
||||
{CN_AUTO_REJOIN, MXS_MODULE_PARAM_BOOL, "false"},
|
||||
{CN_NO_PROMOTE_SERVERS, MXS_MODULE_PARAM_SERVERLIST},
|
||||
{CN_PROMOTION_SQL_FILE, MXS_MODULE_PARAM_PATH},
|
||||
{CN_DEMOTION_SQL_FILE, MXS_MODULE_PARAM_PATH},
|
||||
{MXS_END_MODULE_PARAMS}
|
||||
}
|
||||
};
|
||||
|
@ -24,6 +24,8 @@
|
||||
|
||||
extern const int PORT_UNKNOWN;
|
||||
extern const char * const CN_AUTO_FAILOVER;
|
||||
extern const char * const CN_PROMOTION_SQL_FILE;
|
||||
extern const char * const CN_DEMOTION_SQL_FILE;
|
||||
|
||||
class MariaDBMonitor;
|
||||
|
||||
@ -140,6 +142,8 @@ private:
|
||||
int m_master_failure_timeout; /**< Master failure verification (via slaves) time in seconds */
|
||||
ServerArray m_excluded_servers; /**< Servers banned for master promotion during auto-failover or
|
||||
* autoselect switchover. */
|
||||
std::string m_promote_sql_file; /**< File with sql commands which are ran to a server being promoted. */
|
||||
std::string m_demote_sql_file; /**< File with sql commands which are ran to a server being demoted. */
|
||||
|
||||
// Other settings
|
||||
std::string m_script; /**< Script to call when state changes occur on servers */
|
||||
@ -210,7 +214,7 @@ private:
|
||||
void handle_auto_rejoin();
|
||||
bool get_joinable_servers(ServerArray* output);
|
||||
bool server_is_rejoin_suspect(MariaDBServer* rejoin_cand, json_t** output);
|
||||
uint32_t do_rejoin(const ServerArray& joinable_servers);
|
||||
uint32_t do_rejoin(const ServerArray& joinable_servers, json_t** output);
|
||||
|
||||
// Methods common to failover/switchover/rejoin
|
||||
MariaDBServer* select_new_master(ServerArray* slaves_out, json_t** err_out);
|
||||
@ -226,6 +230,7 @@ private:
|
||||
int seconds_remaining);
|
||||
void disable_setting(const char* setting);
|
||||
void load_journal();
|
||||
bool check_sql_files();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "mariadbserver.hh"
|
||||
|
||||
#include <fstream>
|
||||
#include <inttypes.h>
|
||||
#include <sstream>
|
||||
#include <maxscale/mysql_utils.h>
|
||||
@ -637,6 +638,51 @@ bool MariaDBServer::failover_wait_relay_log(int seconds_remaining, json_t** err_
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool MariaDBServer::run_sql_from_file(const string& path, json_t** error_out)
|
||||
{
|
||||
MYSQL* conn = server_base->con;
|
||||
bool error = false;
|
||||
std::ifstream sql_file(path);
|
||||
if (sql_file.is_open())
|
||||
{
|
||||
MXS_NOTICE("Executing sql queries from file '%s'.", path.c_str());
|
||||
int lines_executed = 0;
|
||||
|
||||
while (!sql_file.eof() && !error)
|
||||
{
|
||||
string line;
|
||||
std::getline(sql_file, line);
|
||||
if (sql_file.bad())
|
||||
{
|
||||
PRINT_MXS_JSON_ERROR(error_out, "Error when reading sql text file '%s': '%s'.",
|
||||
path.c_str(), mxs_strerror(errno));
|
||||
error = true;
|
||||
}
|
||||
// Skip empty lines and comment lines
|
||||
else if (!line.empty() && line[0] != '#')
|
||||
{
|
||||
if (mxs_mysql_query(conn, line.c_str()) == 0)
|
||||
{
|
||||
lines_executed++;
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINT_MXS_JSON_ERROR(error_out, "Failed to execute sql from text file '%s'. Query: '%s'. "
|
||||
"Error: '%s'.", path.c_str(), line.c_str(), mysql_error(conn));
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
MXS_NOTICE("%d queries executed successfully.", lines_executed);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINT_MXS_JSON_ERROR(error_out, "Could not open sql text file '%s'.", path.c_str());
|
||||
error = true;
|
||||
}
|
||||
return !error;
|
||||
}
|
||||
|
||||
QueryResult::QueryResult(MYSQL_RES* resultset)
|
||||
: m_resultset(resultset)
|
||||
, m_columns(-1)
|
||||
|
@ -264,6 +264,16 @@ public:
|
||||
* or an error occurred.
|
||||
*/
|
||||
bool failover_wait_relay_log(int seconds_remaining, json_t** err_out);
|
||||
|
||||
/**
|
||||
* Read the file contents and send them as sql queries to the server. Queries should not return any data.
|
||||
*
|
||||
* @param server Server to send queries to
|
||||
* @param path Text file path.
|
||||
* @param error_out Error output
|
||||
* @return True if file was read and all commands were completed successfully
|
||||
*/
|
||||
bool run_sql_from_file(const std::string& path, json_t** error_out);
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user