Different cluster operations use different parameter types

Only the parameters used by all operations are in the common class.
This commit is contained in:
Esa Korhonen
2018-10-19 15:23:25 +03:00
parent a4ce4e4613
commit 184e187732
4 changed files with 108 additions and 136 deletions

View File

@ -58,12 +58,12 @@ bool MariaDBMonitor::manual_switchover(SERVER* promotion_server, SERVER* demotio
switchover_done = switchover_perform(*op); switchover_done = switchover_perform(*op);
if (switchover_done) if (switchover_done)
{ {
MXS_NOTICE(SWITCHOVER_OK, op->demotion_target->name(), op->promotion_target->name()); MXS_NOTICE(SWITCHOVER_OK, op->demotion.target->name(), op->promotion.target->name());
} }
else else
{ {
string msg = string_printf(SWITCHOVER_FAIL, string msg = string_printf(SWITCHOVER_FAIL,
op->demotion_target->name(), op->promotion_target->name()); op->demotion.target->name(), op->promotion.target->name());
bool failover_setting = config_get_bool(m_monitor->parameters, CN_AUTO_FAILOVER); bool failover_setting = config_get_bool(m_monitor->parameters, CN_AUTO_FAILOVER);
if (failover_setting) if (failover_setting)
{ {
@ -90,12 +90,12 @@ bool MariaDBMonitor::manual_failover(json_t** output)
failover_done = failover_perform(*op); failover_done = failover_perform(*op);
if (failover_done) if (failover_done)
{ {
MXS_NOTICE(FAILOVER_OK, op->demotion_target->name(), op->promotion_target->name()); MXS_NOTICE(FAILOVER_OK, op->demotion_target->name(), op->promotion.target->name());
} }
else else
{ {
PRINT_MXS_JSON_ERROR(output, FAILOVER_FAIL, PRINT_MXS_JSON_ERROR(output, FAILOVER_FAIL,
op->demotion_target->name(), op->promotion_target->name()); op->demotion_target->name(), op->promotion.target->name());
} }
} }
else else
@ -424,12 +424,12 @@ int MariaDBMonitor::redirect_slaves(MariaDBServer* new_master, const ServerArray
* @param redirected_to_demo Output for slaves successfully redirected to demotion target * @param redirected_to_demo Output for slaves successfully redirected to demotion target
* @return The number of slaves successfully redirected * @return The number of slaves successfully redirected
*/ */
int MariaDBMonitor::redirect_slaves_ex(ClusterOperation& op, int MariaDBMonitor::redirect_slaves_ex(GeneralOpData& general, OperationType type,
const MariaDBServer* promotion_target,
const MariaDBServer* demotion_target,
ServerArray* redirected_to_promo, ServerArray* redirected_to_demo) ServerArray* redirected_to_promo, ServerArray* redirected_to_demo)
{ {
mxb_assert(op.type == OperationType::SWITCHOVER || op.type == OperationType::FAILOVER); mxb_assert(type == OperationType::SWITCHOVER || type == OperationType::FAILOVER);
MariaDBServer* const promotion_target = op.promotion_target;
MariaDBServer* const demotion_target = op.demotion_target;
// Slaves of demotion target are redirected to promotion target. // Slaves of demotion target are redirected to promotion target.
// Try to redirect even disconnected slaves. // Try to redirect even disconnected slaves.
@ -437,7 +437,7 @@ int MariaDBMonitor::redirect_slaves_ex(ClusterOperation& op,
// Slaves of promotion target are redirected to demotion target in case of switchover. // Slaves of promotion target are redirected to demotion target in case of switchover.
// This list contains elements only when promoting a relay in switchover. // This list contains elements only when promoting a relay in switchover.
ServerArray redirect_to_demo_target; ServerArray redirect_to_demo_target;
if (op.type == OperationType::SWITCHOVER) if (type == OperationType::SWITCHOVER)
{ {
redirect_to_demo_target = get_redirectables(promotion_target, demotion_target); redirect_to_demo_target = get_redirectables(promotion_target, demotion_target);
} }
@ -463,7 +463,7 @@ int MariaDBMonitor::redirect_slaves_ex(ClusterOperation& op,
const char redir_fmt[] = "Redirecting %s to replicate from %s instead of %s."; const char redir_fmt[] = "Redirecting %s to replicate from %s instead of %s.";
string slave_names_to_promo = monitored_servers_to_string(redirect_to_promo_target); string slave_names_to_promo = monitored_servers_to_string(redirect_to_promo_target);
string slave_names_to_demo = monitored_servers_to_string(redirect_to_demo_target); string slave_names_to_demo = monitored_servers_to_string(redirect_to_demo_target);
mxb_assert(slave_names_to_demo.empty() || op.type == OperationType::SWITCHOVER); mxb_assert(slave_names_to_demo.empty() || type == OperationType::SWITCHOVER);
// Print both name lists if both have items, otherwise just the one with items. // Print both name lists if both have items, otherwise just the one with items.
if (!slave_names_to_promo.empty() && !slave_names_to_demo.empty()) if (!slave_names_to_promo.empty() && !slave_names_to_demo.empty())
@ -488,7 +488,7 @@ int MariaDBMonitor::redirect_slaves_ex(ClusterOperation& op,
int fails = 0; int fails = 0;
int conflicts = 0; int conflicts = 0;
auto redirection_helper = auto redirection_helper =
[this, &op, &conflicts, &successes, &fails](ServerArray& redirect_these, [this, &general, &conflicts, &successes, &fails](ServerArray& redirect_these,
const MariaDBServer* from, const MariaDBServer* to, const MariaDBServer* from, const MariaDBServer* to,
ServerArray* redirected) { ServerArray* redirected) {
for (MariaDBServer* redirectable : redirect_these) for (MariaDBServer* redirectable : redirect_these)
@ -510,7 +510,7 @@ int MariaDBMonitor::redirect_slaves_ex(ClusterOperation& op,
else else
{ {
// No conflict, redirect as normal. // No conflict, redirect as normal.
if (redirectable->redirect_existing_slave_conn(op.general, from, to)) if (redirectable->redirect_existing_slave_conn(general, from, to))
{ {
successes++; successes++;
redirected->push_back(redirectable); redirected->push_back(redirectable);
@ -769,16 +769,17 @@ bool MariaDBMonitor::server_is_rejoin_suspect(MariaDBServer* rejoin_cand, json_t
* @param op Operation descriptor * @param op Operation descriptor
* @return True if successful. If false, replication may be broken. * @return True if successful. If false, replication may be broken.
*/ */
bool MariaDBMonitor::switchover_perform(ClusterOperation& op) bool MariaDBMonitor::switchover_perform(SwitchoverParams& op)
{ {
mxb_assert(op.demotion && op.promotion); mxb_assert(op.demotion.target && op.promotion.target);
MariaDBServer* const promotion_target = op.promotion->target; const OperationType type = OperationType::SWITCHOVER;
MariaDBServer* const demotion_target = op.demotion->target; MariaDBServer* const promotion_target = op.promotion.target;
MariaDBServer* const demotion_target = op.demotion.target;
json_t** const error_out = op.general.error_out; json_t** const error_out = op.general.error_out;
bool rval = false; bool rval = false;
// Step 1: Set read-only to on, flush logs, update gtid:s. // Step 1: Set read-only to on, flush logs, update gtid:s.
if (demotion_target->demote(*op.demotion, op.general)) if (demotion_target->demote(op.demotion, op.general))
{ {
m_cluster_modified = true; m_cluster_modified = true;
bool catchup_and_promote_success = false; bool catchup_and_promote_success = false;
@ -790,13 +791,13 @@ bool MariaDBMonitor::switchover_perform(ClusterOperation& op)
{ {
MXS_INFO("Switchover: Catchup took %.1f seconds.", timer.lap().secs()); MXS_INFO("Switchover: Catchup took %.1f seconds.", timer.lap().secs());
// Step 3: On new master: remove slave connections, set read-only to OFF etc. // Step 3: On new master: remove slave connections, set read-only to OFF etc.
if (promotion_target->promote(op.general, *op.promotion, op.type, demotion_target)) if (promotion_target->promote(op.general, op.promotion, type, demotion_target))
{ {
// Point of no return. Even if following steps fail, do not try to undo. // Point of no return. Even if following steps fail, do not try to undo.
// Switchover considered at least partially successful. // Switchover considered at least partially successful.
catchup_and_promote_success = true; catchup_and_promote_success = true;
rval = true; rval = true;
if (op.promotion->to_from_master) if (op.promotion.to_from_master)
{ {
// Force a master swap on next tick. // Force a master swap on next tick.
m_next_master = promotion_target; m_next_master = promotion_target;
@ -804,7 +805,7 @@ bool MariaDBMonitor::switchover_perform(ClusterOperation& op)
// Step 4: Start replication on old master and redirect slaves. // Step 4: Start replication on old master and redirect slaves.
ServerArray redirected_to_promo_target; ServerArray redirected_to_promo_target;
if (demotion_target->copy_slave_conns(op.general, op.demotion->conns_to_copy, if (demotion_target->copy_slave_conns(op.general, op.demotion.conns_to_copy,
promotion_target)) promotion_target))
{ {
redirected_to_promo_target.push_back(demotion_target); redirected_to_promo_target.push_back(demotion_target);
@ -815,14 +816,15 @@ bool MariaDBMonitor::switchover_perform(ClusterOperation& op)
promotion_target->name(), demotion_target->name()); promotion_target->name(), demotion_target->name());
} }
ServerArray redirected_to_demo_target; ServerArray redirected_to_demo_target;
redirect_slaves_ex(op, &redirected_to_promo_target, &redirected_to_demo_target); redirect_slaves_ex(op.general, type, promotion_target, demotion_target,
&redirected_to_promo_target, &redirected_to_demo_target);
if (!redirected_to_promo_target.empty() || !redirected_to_demo_target.empty()) if (!redirected_to_promo_target.empty() || !redirected_to_demo_target.empty())
{ {
timer.restart(); timer.restart();
// Step 5: Finally, check that slaves are replicating. // Step 5: Finally, check that slaves are replicating.
wait_cluster_stabilization(op, redirected_to_promo_target, promotion_target); wait_cluster_stabilization(op.general, redirected_to_promo_target, promotion_target);
wait_cluster_stabilization(op, redirected_to_demo_target, demotion_target); wait_cluster_stabilization(op.general, redirected_to_demo_target, demotion_target);
auto step6_duration = timer.lap(); auto step6_duration = timer.lap();
MXS_INFO("Switchover: slave replication confirmation took %.1f seconds with " MXS_INFO("Switchover: slave replication confirmation took %.1f seconds with "
"%.1f seconds to spare.", "%.1f seconds to spare.",
@ -863,20 +865,22 @@ bool MariaDBMonitor::switchover_perform(ClusterOperation& op)
* @param op Operation descriptor * @param op Operation descriptor
* @return True if successful * @return True if successful
*/ */
bool MariaDBMonitor::failover_perform(ClusterOperation& op) bool MariaDBMonitor::failover_perform(FailoverParams& op)
{ {
mxb_assert(op.promotion_target && op.demotion_target); mxb_assert(op.promotion.target && op.demotion_target);
MariaDBServer* const promotion_target = op.promotion_target; const OperationType type = OperationType::FAILOVER;
MariaDBServer* const promotion_target = op.promotion.target;
auto const demotion_target = op.demotion_target;
bool rval = false; bool rval = false;
// Step 1: Stop and reset slave, set read-only to OFF. // Step 1: Stop and reset slave, set read-only to OFF.
if (promotion_target->promote(op.general, *op.promotion, op.type, op.demotion_target)) if (promotion_target->promote(op.general, op.promotion, type, demotion_target))
{ {
// Point of no return. Even if following steps fail, do not try to undo. Failover considered // Point of no return. Even if following steps fail, do not try to undo. Failover considered
// at least partially successful. // at least partially successful.
rval = true; rval = true;
m_cluster_modified = true; m_cluster_modified = true;
if (op.promotion->to_from_master) if (op.promotion.to_from_master)
{ {
// Force a master swap on next tick. // Force a master swap on next tick.
m_next_master = promotion_target; m_next_master = promotion_target;
@ -884,14 +888,14 @@ bool MariaDBMonitor::failover_perform(ClusterOperation& op)
// Step 2: Redirect slaves. // Step 2: Redirect slaves.
ServerArray redirected_slaves; ServerArray redirected_slaves;
redirect_slaves_ex(op, &redirected_slaves, NULL); redirect_slaves_ex(op.general, type, promotion_target, demotion_target, &redirected_slaves, NULL);
if (!redirected_slaves.empty()) if (!redirected_slaves.empty())
{ {
StopWatch timer; StopWatch timer;
/* Step 3: Finally, check that slaves are connected to the new master. Even if /* Step 3: Finally, check that slaves are connected to the new master. Even if
* time is out at this point, wait_cluster_stabilization() will check the slaves * time is out at this point, wait_cluster_stabilization() will check the slaves
* once so that latest status is printed. */ * once so that latest status is printed. */
wait_cluster_stabilization(op, redirected_slaves, promotion_target); wait_cluster_stabilization(op.general, redirected_slaves, promotion_target);
MXS_INFO("Failover: slave replication confirmation took %.1f seconds with " MXS_INFO("Failover: slave replication confirmation took %.1f seconds with "
"%.1f seconds to spare.", "%.1f seconds to spare.",
timer.lap().secs(), op.general.time_remaining.secs()); timer.lap().secs(), op.general.time_remaining.secs());
@ -908,7 +912,7 @@ bool MariaDBMonitor::failover_perform(ClusterOperation& op)
* @param redirected_slaves Slaves to check * @param redirected_slaves Slaves to check
* @param new_master The target server of the slave connections * @param new_master The target server of the slave connections
*/ */
void MariaDBMonitor::wait_cluster_stabilization(ClusterOperation& op, const ServerArray& redirected_slaves, void MariaDBMonitor::wait_cluster_stabilization(GeneralOpData& op, const ServerArray& redirected_slaves,
const MariaDBServer* new_master) const MariaDBServer* new_master)
{ {
if (redirected_slaves.empty()) if (redirected_slaves.empty())
@ -917,6 +921,7 @@ void MariaDBMonitor::wait_cluster_stabilization(ClusterOperation& op, const Serv
return; return;
} }
maxbase::Duration& time_remaining = op.time_remaining;
StopWatch timer; StopWatch timer;
// Check all the servers in the list. Using a set because erasing from container. // Check all the servers in the list. Using a set because erasing from container.
std::set<MariaDBServer*> unconfirmed(redirected_slaves.begin(), redirected_slaves.end()); std::set<MariaDBServer*> unconfirmed(redirected_slaves.begin(), redirected_slaves.end());
@ -979,10 +984,10 @@ void MariaDBMonitor::wait_cluster_stabilization(ClusterOperation& op, const Serv
} }
} }
op.general.time_remaining -= timer.lap(); time_remaining -= timer.lap();
if (!unconfirmed.empty()) if (!unconfirmed.empty())
{ {
if (op.general.time_remaining.secs() > 0) if (time_remaining.secs() > 0)
{ {
double standard_sleep = 0.5; // In seconds. double standard_sleep = 0.5; // In seconds.
// If we have unconfirmed slaves and have time remaining, sleep a bit and try again. // If we have unconfirmed slaves and have time remaining, sleep a bit and try again.
@ -990,8 +995,8 @@ void MariaDBMonitor::wait_cluster_stabilization(ClusterOperation& op, const Serv
* all operations for failover/switchover are complete. The sleep is only required to * all operations for failover/switchover are complete. The sleep is only required to
* get correct messages to the user. Think about removing it, or shortening the maximum * get correct messages to the user. Think about removing it, or shortening the maximum
* time of this function. */ * time of this function. */
Duration sleep_time = (op.general.time_remaining.secs() > standard_sleep) ? Duration sleep_time = (time_remaining.secs() > standard_sleep) ?
Duration(standard_sleep) : op.general.time_remaining; Duration(standard_sleep) : time_remaining;
std::this_thread::sleep_for(sleep_time); std::this_thread::sleep_for(sleep_time);
} }
else else
@ -1022,7 +1027,7 @@ void MariaDBMonitor::wait_cluster_stabilization(ClusterOperation& op, const Serv
MXS_WARNING(MSG, fails, new_master->name(), repl_fails.size(), query_fails.size(), MXS_WARNING(MSG, fails, new_master->name(), repl_fails.size(), query_fails.size(),
unconfirmed.size(), new_master->name()); unconfirmed.size(), new_master->name());
} }
op.general.time_remaining -= timer.lap(); time_remaining -= timer.lap();
} }
/** /**
@ -1257,7 +1262,7 @@ bool MariaDBMonitor::is_candidate_better(const MariaDBServer* candidate, const M
* @param error_out Error output * @param error_out Error output
* @return Operation object if cluster is suitable and failover may proceed, or NULL on error * @return Operation object if cluster is suitable and failover may proceed, or NULL on error
*/ */
unique_ptr<ClusterOperation> MariaDBMonitor::failover_prepare(Log log_mode, json_t** error_out) unique_ptr<MariaDBMonitor::FailoverParams> MariaDBMonitor::failover_prepare(Log log_mode, json_t** error_out)
{ {
// This function resembles 'switchover_prepare', but does not yet support manual selection. // This function resembles 'switchover_prepare', but does not yet support manual selection.
@ -1303,7 +1308,7 @@ unique_ptr<ClusterOperation> MariaDBMonitor::failover_prepare(Log log_mode, json
gtid_ok = check_gtid_replication(log_mode, demotion_target, error_out); gtid_ok = check_gtid_replication(log_mode, demotion_target, error_out);
} }
unique_ptr<ClusterOperation> rval; unique_ptr<FailoverParams> rval;
if (promotion_target && demotion_target && gtid_ok) if (promotion_target && demotion_target && gtid_ok)
{ {
const SlaveStatus* slave_conn = promotion_target->slave_connection_status(demotion_target); const SlaveStatus* slave_conn = promotion_target->slave_connection_status(demotion_target);
@ -1351,13 +1356,11 @@ unique_ptr<ClusterOperation> MariaDBMonitor::failover_prepare(Log log_mode, json
// The Duration ctor taking a double interprets is as seconds. // The Duration ctor taking a double interprets is as seconds.
auto time_limit = maxbase::Duration((double)m_failover_timeout); auto time_limit = maxbase::Duration((double)m_failover_timeout);
bool promoting_to_master = (demotion_target == m_master); bool promoting_to_master = (demotion_target == m_master);
ServerOperation* promotion_op = new ServerOperation(promotion_target, promoting_to_master, ServerOperation promotion(promotion_target, promoting_to_master,
m_handle_event_scheduler, m_promote_sql_file, m_handle_event_scheduler, m_promote_sql_file,
demotion_target->m_slave_status); demotion_target->m_slave_status);
rval.reset(new ClusterOperation(OperationType::FAILOVER, NULL, promotion_op, GeneralOpData general(m_replication_user, m_replication_password, error_out, time_limit);
promotion_target, demotion_target, rval.reset(new FailoverParams(promotion, demotion_target, general));
m_replication_user, m_replication_password,
error_out, time_limit));
} }
} }
return rval; return rval;
@ -1409,11 +1412,11 @@ void MariaDBMonitor::handle_auto_failover()
MXS_NOTICE("Performing automatic failover to replace failed master '%s'.", m_master->name()); MXS_NOTICE("Performing automatic failover to replace failed master '%s'.", m_master->name());
if (failover_perform(*op)) if (failover_perform(*op))
{ {
MXS_NOTICE(FAILOVER_OK, op->demotion_target->name(), op->promotion_target->name()); MXS_NOTICE(FAILOVER_OK, op->demotion_target->name(), op->promotion.target->name());
} }
else else
{ {
MXS_ERROR(FAILOVER_FAIL, op->demotion_target->name(), op->promotion_target->name()); MXS_ERROR(FAILOVER_FAIL, op->demotion_target->name(), op->promotion.target->name());
report_and_disable("failover", CN_AUTO_FAILOVER, &m_auto_failover); report_and_disable("failover", CN_AUTO_FAILOVER, &m_auto_failover);
} }
} }
@ -1545,9 +1548,8 @@ const MariaDBServer* MariaDBMonitor::slave_receiving_events(const MariaDBServer*
* @param error_out Error output * @param error_out Error output
* @return Operation object if cluster is suitable and switchover may proceed, or NULL on error * @return Operation object if cluster is suitable and switchover may proceed, or NULL on error
*/ */
unique_ptr<ClusterOperation> MariaDBMonitor::switchover_prepare(SERVER* promotion_server, unique_ptr<MariaDBMonitor::SwitchoverParams>
SERVER* demotion_server, MariaDBMonitor::switchover_prepare(SERVER* promotion_server, SERVER* demotion_server, Log log_mode,
Log log_mode,
json_t** error_out) json_t** error_out)
{ {
// Check that both servers are ok if specified, or autoselect them. Demotion target must be checked // Check that both servers are ok if specified, or autoselect them. Demotion target must be checked
@ -1642,21 +1644,17 @@ unique_ptr<ClusterOperation> MariaDBMonitor::switchover_prepare(SERVER* promotio
gtid_ok = check_gtid_replication(log_mode, demotion_target, error_out); gtid_ok = check_gtid_replication(log_mode, demotion_target, error_out);
} }
unique_ptr<ClusterOperation> rval; unique_ptr<SwitchoverParams> rval;
if (promotion_target && demotion_target && gtid_ok) if (promotion_target && demotion_target && gtid_ok)
{ {
maxbase::Duration time_limit((double)m_switchover_timeout); maxbase::Duration time_limit((double)m_switchover_timeout);
bool master_swap = demotion_target->is_master(); bool master_swap = (demotion_target == m_master);
ServerOperation* demotion_op = new ServerOperation(demotion_target, master_swap, ServerOperation promotion(promotion_target, master_swap, m_handle_event_scheduler,
m_handle_event_scheduler, m_demote_sql_file, m_promote_sql_file, demotion_target->m_slave_status);
promotion_target->m_slave_status); ServerOperation demotion(demotion_target, master_swap, m_handle_event_scheduler,
ServerOperation* promotion_op = new ServerOperation(promotion_target, master_swap, m_demote_sql_file, promotion_target->m_slave_status);
m_handle_event_scheduler, m_promote_sql_file, GeneralOpData general(m_replication_user, m_replication_password, error_out, time_limit);
demotion_target->m_slave_status); rval.reset(new SwitchoverParams(promotion, demotion, general));
rval.reset(new ClusterOperation(op_type, demotion_op, promotion_op,
promotion_target, demotion_target,
m_replication_user, m_replication_password,
error_out, time_limit));
} }
return rval; return rval;
} }
@ -1702,13 +1700,12 @@ void MariaDBMonitor::handle_low_disk_space_master()
bool switched = switchover_perform(*op); bool switched = switchover_perform(*op);
if (switched) if (switched)
{ {
MXS_NOTICE(SWITCHOVER_OK, op->demotion_target->name(), op->promotion_target->name()); MXS_NOTICE(SWITCHOVER_OK, op->demotion.target->name(), op->promotion.target->name());
} }
else else
{ {
MXS_ERROR(SWITCHOVER_FAIL, op->demotion_target->name(), op->promotion_target->name()); MXS_ERROR(SWITCHOVER_FAIL, op->demotion.target->name(), op->promotion.target->name());
report_and_disable("switchover", report_and_disable("switchover", CN_SWITCHOVER_ON_LOW_DISK_SPACE,
CN_SWITCHOVER_ON_LOW_DISK_SPACE,
&m_switchover_on_low_disk_space); &m_switchover_on_low_disk_space);
} }
} }
@ -1829,21 +1826,20 @@ ServerArray MariaDBMonitor::get_redirectables(const MariaDBServer* old_master,
return redirectable_slaves; return redirectable_slaves;
} }
ClusterOperation::ClusterOperation(OperationType type, ServerOperation* dem_op, ServerOperation* prom_op, MariaDBMonitor::SwitchoverParams::SwitchoverParams(const ServerOperation& promotion,
MariaDBServer* promotion_target, MariaDBServer* demotion_target, const ServerOperation& demotion,
string& replication_user, string& replication_password, const GeneralOpData& general)
json_t** error, maxbase::Duration time_remaining) : promotion(promotion)
: type(type) , demotion(demotion)
, demotion(dem_op) , general(general)
, promotion(prom_op)
, general(type, replication_user, replication_password, error, time_remaining)
, promotion_target(promotion_target)
, demotion_target(demotion_target)
{ {
} }
ClusterOperation::~ClusterOperation() MariaDBMonitor::FailoverParams::FailoverParams(const ServerOperation& promotion,
const MariaDBServer* demotion_target,
const GeneralOpData& general)
: promotion(promotion)
, demotion_target(demotion_target)
, general(general)
{ {
delete demotion;
delete promotion;
} }

View File

@ -36,33 +36,6 @@ typedef std::unordered_map<int64_t, MariaDBServer*> IdToServerMap;
// Map of cycle number to cycle members. The elements should be ordered for predictability when iterating. // Map of cycle number to cycle members. The elements should be ordered for predictability when iterating.
typedef std::map<int, ServerArray> CycleMap; typedef std::map<int, ServerArray> CycleMap;
/**
* Class which encapsulates many settings and status descriptors for a failover/switchover.
* Is more convenient to pass around than the separate elements. Most fields are constants or constant
* pointers since they should not change during an operation.
*/
class ClusterOperation
{
private:
ClusterOperation(const ClusterOperation&) = delete;
ClusterOperation& operator=(const ClusterOperation&) = delete;
public:
const OperationType type; // Failover or switchover
ServerOperation* const demotion; // Required by MariaDBServer->demote()
ServerOperation* const promotion; // Required by MariaDBServer->promote()
GeneralOpData general; // General operation data
MariaDBServer* const promotion_target; // Which server will be promoted
MariaDBServer* const demotion_target; // Which server will be demoted
ClusterOperation(OperationType type, ServerOperation* dem_op, ServerOperation* prom_op,
MariaDBServer* promotion_target, MariaDBServer* demotion_target,
std::string& replication_user, std::string& replication_password,
json_t** error, maxbase::Duration time_remaining);
~ClusterOperation();
};
// MariaDB Monitor instance data // MariaDB Monitor instance data
class MariaDBMonitor : public maxscale::MonitorInstance class MariaDBMonitor : public maxscale::MonitorInstance
{ {
@ -147,23 +120,26 @@ private:
ON ON
}; };
class FailoverParams
{
public:
const MariaDBServer* const demotion_target;
ServerOperation promotion; // Required by MariaDBServer->promote()
GeneralOpData general;
FailoverParams(const MariaDBServer* demotion_target, ServerOperation promotion,
GeneralOpData general);
};
class SwitchoverParams class SwitchoverParams
{ {
public: public:
ServerOperation demotion; // Required by MariaDBServer->demote() ServerOperation promotion;
ServerOperation promotion; // Required by MariaDBServer->promote() ServerOperation demotion;
GeneralOpData general; GeneralOpData general;
SwitchoverParams(const ServerOperation& promotion, const ServerOperation& demotion,
const GeneralOpData& general);
};
class FailoverParams
{
public:
ServerOperation promotion; // Required by MariaDBServer->promote()
const MariaDBServer* const demotion_target;
GeneralOpData general;
FailoverParams(const ServerOperation& promotion, const MariaDBServer* demotion_target,
const GeneralOpData& general);
}; };
// Information about a multimaster group (replication cycle) // Information about a multimaster group (replication cycle)
@ -312,12 +288,12 @@ private:
const MariaDBServer* slave_receiving_events(const MariaDBServer* demotion_target, const MariaDBServer* slave_receiving_events(const MariaDBServer* demotion_target,
maxbase::Duration* event_age_out, maxbase::Duration* event_age_out,
maxbase::Duration* delay_out); maxbase::Duration* delay_out);
std::unique_ptr<ClusterOperation> switchover_prepare(SERVER* new_master, SERVER* current_master, std::unique_ptr<SwitchoverParams> switchover_prepare(SERVER* new_master, SERVER* current_master,
Log log_mode, json_t** error_out); Log log_mode, json_t** error_out);
std::unique_ptr<ClusterOperation> failover_prepare(Log log_mode, json_t** error_out); std::unique_ptr<FailoverParams> failover_prepare(Log log_mode, json_t** error_out);
bool switchover_perform(ClusterOperation& operation); bool switchover_perform(SwitchoverParams& operation);
bool failover_perform(ClusterOperation& operation); bool failover_perform(FailoverParams& op);
// Methods used by failover/switchover/rejoin // Methods used by failover/switchover/rejoin
MariaDBServer* select_promotion_target(MariaDBServer* current_master, OperationType op, MariaDBServer* select_promotion_target(MariaDBServer* current_master, OperationType op,
@ -332,11 +308,15 @@ private:
ServerArray get_redirectables(const MariaDBServer* old_master, const MariaDBServer* ignored_slave); ServerArray get_redirectables(const MariaDBServer* old_master, const MariaDBServer* ignored_slave);
int redirect_slaves(MariaDBServer* new_master, const ServerArray& slaves, int redirect_slaves(MariaDBServer* new_master, const ServerArray& slaves,
ServerArray* redirected_slaves); ServerArray* redirected_slaves);
int redirect_slaves_ex(ClusterOperation& op, int redirect_slaves_ex(GeneralOpData& op,
ServerArray* redirected_to_promo, ServerArray* redirected_to_demo); OperationType type,
const MariaDBServer* promotion_target,
const MariaDBServer* demotion_target,
ServerArray* redirected_to_promo,
ServerArray* redirected_to_demo);
bool start_external_replication(MariaDBServer* new_master, json_t** err_out); bool start_external_replication(MariaDBServer* new_master, json_t** err_out);
std::string generate_change_master_cmd(const std::string& master_host, int master_port); std::string generate_change_master_cmd(const std::string& master_host, int master_port);
void wait_cluster_stabilization(ClusterOperation& op, const ServerArray& slaves, void wait_cluster_stabilization(GeneralOpData& op, const ServerArray& slaves,
const MariaDBServer* new_master); const MariaDBServer* new_master);
void report_and_disable(const std::string& operation, const std::string& setting_name, void report_and_disable(const std::string& operation, const std::string& setting_name,
bool* setting_var); bool* setting_var);

View File

@ -166,10 +166,9 @@ ServerOperation::ServerOperation(MariaDBServer* target, bool was_is_master,
{ {
} }
GeneralOpData::GeneralOpData(OperationType type, const string& replication_user, const string& replication_password, GeneralOpData::GeneralOpData(const string& replication_user, const string& replication_password,
json_t** error, maxbase::Duration time_remaining) json_t** error, maxbase::Duration time_remaining)
: type(type) : replication_user(replication_user)
, replication_user(replication_user)
, replication_password(replication_password) , replication_password(replication_password)
, error_out(error) , error_out(error)
, time_remaining(time_remaining) , time_remaining(time_remaining)

View File

@ -217,18 +217,15 @@ enum class OperationType
FAILOVER FAILOVER
}; };
class ServerOperation;
class GeneralOpData class GeneralOpData
{ {
public: public:
const OperationType type;
const std::string replication_user; // User for CHANGE MASTER TO ... const std::string replication_user; // User for CHANGE MASTER TO ...
const std::string replication_password; // Password for CHANGE MASTER TO ... const std::string replication_password; // Password for CHANGE MASTER TO ...
json_t** const error_out; // Json error output json_t** const error_out; // Json error output
maxbase::Duration time_remaining; // How much time remains to complete the operation maxbase::Duration time_remaining; // How much time remains to complete the operation
GeneralOpData(OperationType type, GeneralOpData(const std::string& replication_user, const std::string& replication_password,
const std::string& replication_user, const std::string& replication_password,
json_t** error, maxbase::Duration time_remaining); json_t** error, maxbase::Duration time_remaining);
}; };