MXS-2273 Set SERVER_BEING_DRAINED properly

The maintenance and being-drained modes are now set using the same
mechanism.
This commit is contained in:
Johan Wikman
2019-01-28 15:22:02 +02:00
parent e3d74bd18d
commit bc4a52acb0
2 changed files with 58 additions and 30 deletions

View File

@ -134,9 +134,11 @@ public:
/** /**
* Maintenance mode request constants. * Maintenance mode request constants.
*/ */
static const int SERVER_NO_CHANGE = 0; static const int SERVER_NO_CHANGE = 0;
static const int SERVER_MAINT_OFF = 1; static const int SERVER_MAINT_OFF = 1;
static const int SERVER_MAINT_ON = 2; static const int SERVER_MAINT_ON = 2;
static const int SERVER_BEING_DRAINED_OFF = 3;
static const int SERVER_BEING_DRAINED_ON = 4;
SERVER* server = nullptr; /**< The server being monitored */ SERVER* server = nullptr; /**< The server being monitored */
MYSQL* con = nullptr; /**< The MySQL connection */ MYSQL* con = nullptr; /**< The MySQL connection */

View File

@ -1588,8 +1588,7 @@ void monitor_check_maintenance_requests(Monitor* monitor)
{ {
/* In theory, the admin may be modifying the server maintenance status during this function. The overall /* In theory, the admin may be modifying the server maintenance status during this function. The overall
* maintenance flag should be read-written atomically to prevent missing a value. */ * maintenance flag should be read-written atomically to prevent missing a value. */
int flags_changed = atomic_exchange_int(&monitor->check_status_flag, int flags_changed = atomic_exchange_int(&monitor->check_status_flag, Monitor::STATUS_FLAG_NOCHECK);
Monitor::STATUS_FLAG_NOCHECK);
if (flags_changed != Monitor::STATUS_FLAG_NOCHECK) if (flags_changed != Monitor::STATUS_FLAG_NOCHECK)
{ {
for (auto ptr : monitor->m_servers) for (auto ptr : monitor->m_servers)
@ -1597,14 +1596,31 @@ void monitor_check_maintenance_requests(Monitor* monitor)
// The only server status bit the admin may change is the [Maintenance] bit. // The only server status bit the admin may change is the [Maintenance] bit.
int admin_msg = atomic_exchange_int(&ptr->status_request, int admin_msg = atomic_exchange_int(&ptr->status_request,
MXS_MONITORED_SERVER::SERVER_NO_CHANGE); MXS_MONITORED_SERVER::SERVER_NO_CHANGE);
if (admin_msg == MXS_MONITORED_SERVER::SERVER_MAINT_ON)
switch (admin_msg)
{ {
case MXS_MONITORED_SERVER::SERVER_MAINT_ON:
// TODO: Change to writing MONITORED_SERVER->pending status instead once cleanup done. // TODO: Change to writing MONITORED_SERVER->pending status instead once cleanup done.
ptr->server->set_status(SERVER_MAINT); ptr->server->set_status(SERVER_MAINT);
} break;
else if (admin_msg == MXS_MONITORED_SERVER::SERVER_MAINT_OFF)
{ case MXS_MONITORED_SERVER::SERVER_MAINT_OFF:
ptr->server->clear_status(SERVER_MAINT); ptr->server->clear_status(SERVER_MAINT);
break;
case MXS_MONITORED_SERVER::SERVER_BEING_DRAINED_ON:
ptr->server->set_status(SERVER_BEING_DRAINED);
break;
case MXS_MONITORED_SERVER::SERVER_BEING_DRAINED_OFF:
ptr->server->clear_status(SERVER_BEING_DRAINED);
break;
case MXS_MONITORED_SERVER::SERVER_NO_CHANGE:
break;
default:
mxb_assert(!true);
} }
} }
} }
@ -2383,12 +2399,23 @@ bool Monitor::set_server_status(SERVER* srv, int bit, string* errmsg_out)
*errmsg_out = ERR_CANNOT_MODIFY; *errmsg_out = ERR_CANNOT_MODIFY;
} }
} }
else if (bit & SERVER_MAINT) else
{ {
/* Maintenance is set/cleared using a special variable which the monitor reads when /* Maintenance and being-drained are set/cleared using a special variable which the
* starting the next update cycle. */ * monitor reads when starting the next update cycle. */
int previous_request = atomic_exchange_int(&msrv->status_request,
MXS_MONITORED_SERVER::SERVER_MAINT_ON); int request;
if (bit & SERVER_MAINT)
{
request = MXS_MONITORED_SERVER::SERVER_MAINT_ON;
}
else
{
mxb_assert(bit & SERVER_BEING_DRAINED);
request = MXS_MONITORED_SERVER::SERVER_BEING_DRAINED_ON;
}
int previous_request = atomic_exchange_int(&msrv->status_request, request);
written = true; written = true;
// Warn if the previous request hasn't been read. // Warn if the previous request hasn't been read.
if (previous_request != MXS_MONITORED_SERVER::SERVER_NO_CHANGE) if (previous_request != MXS_MONITORED_SERVER::SERVER_NO_CHANGE)
@ -2398,12 +2425,6 @@ bool Monitor::set_server_status(SERVER* srv, int bit, string* errmsg_out)
// Also set a flag so the next loop happens sooner. // Also set a flag so the next loop happens sooner.
atomic_store_int(&this->check_status_flag, Monitor::STATUS_FLAG_CHECK); atomic_store_int(&this->check_status_flag, Monitor::STATUS_FLAG_CHECK);
} }
else
{
// TODO: This should be set the same way the maintenance bit is set.
srv->set_status(bit);
written = true;
}
} }
else else
{ {
@ -2439,24 +2460,29 @@ bool Monitor::clear_server_status(SERVER* srv, int bit, string* errmsg_out)
*errmsg_out = ERR_CANNOT_MODIFY; *errmsg_out = ERR_CANNOT_MODIFY;
} }
} }
else if (bit & SERVER_MAINT) else
{ {
// Warn if the previous request hasn't been read. int request;
int previous_request = atomic_exchange_int(&msrv->status_request, if (bit & SERVER_MAINT)
MXS_MONITORED_SERVER::SERVER_MAINT_OFF); {
request = MXS_MONITORED_SERVER::SERVER_MAINT_OFF;
}
else
{
mxb_assert(bit & SERVER_BEING_DRAINED);
request = MXS_MONITORED_SERVER::SERVER_BEING_DRAINED_OFF;
}
int previous_request = atomic_exchange_int(&msrv->status_request, request);
written = true; written = true;
// Warn if the previous request hasn't been read.
if (previous_request != MXS_MONITORED_SERVER::SERVER_NO_CHANGE) if (previous_request != MXS_MONITORED_SERVER::SERVER_NO_CHANGE)
{ {
MXS_WARNING(WRN_REQUEST_OVERWRITTEN); MXS_WARNING(WRN_REQUEST_OVERWRITTEN);
} }
// Also set a flag so the next loop happens sooner.
atomic_store_int(&this->check_status_flag, Monitor::STATUS_FLAG_CHECK); atomic_store_int(&this->check_status_flag, Monitor::STATUS_FLAG_CHECK);
} }
else
{
// TODO: This should be set the same way the maintenance bit is set.
srv->clear_status(bit);
written = true;
}
} }
else else
{ {