1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Bug#17638477 UNINSTALL AND INSTALL SEMI-SYNC PLUGIN CAUSES SLAVES TO BREAK

Problem: Uninstallation of semi sync plugin causes replication to
break.

Analysis: A semisync enabled replication is mutual agreement between
Master and Slave when the connection (I/O thread) is established.
Once I/O thread is started and if semisync is enabled on both
master and slave, master appends special magic header to events
using semisync plugin functions and sends it to slave. And slave
expects that each event will have that special magic header format
and reads those bytes using semisync plugin functions.

When semi sync replication is in use if users execute
uninstallation of the plugin on master, slave gets confused while
interpreting that event's content because it expects special 
magic header at the beginning of the event. Slave SQL thread will
be stopped with "Missing magic number in the header" error.

Similar problem will happen if uninstallation of the plugin happens
on slave when semi sync replication is in in use. Master sends
the events with magic header and slave does not know about the
added magic header and thinks that it received a corrupted event.
Hence slave SQL thread stops with "Found  corrupted event" error.

Fix: Uninstallation of semisync plugin will be blocked when semisync
replication is in use and will throw 'ER_UNKNOWN_ERROR' error.
To detect that semisync replication is in use, this patch uses
semisync status variable values.
 > On Master, it checks for 'Rpl_semi_sync_master_status' to be OFF
    before allowing the uninstallation of rpl_semi_sync_master plugin.
    >> Rpl_semi_sync_master_status is OFF when
        >>> there is no dump thread running
        >>> there are no semisync slaves
 > On Slave, it checks for 'Rpl_semi_sync_slave_status' to be OFF
    before allowing the uninstallation of rpl_semi_sync_slave plugin.
    >> Rpl_semi_sync_slave_status is OFF when
       >>> there is no I/O thread running
       >>> replication is asynchronous replication.
This commit is contained in:
Venkatesh Duggirala
2014-05-05 22:22:15 +05:30
parent 16b81798aa
commit 66d624b7d6
11 changed files with 317 additions and 12 deletions

View File

@ -2117,6 +2117,59 @@ void free_status_vars()
delete_dynamic(&all_status_vars);
}
/**
@brief Get the value of given status variable
@param[in] thd thread handler
@param[in] list list of SHOW_VAR objects in which function should
search
@param[in] name name of the status variable
@param[in/out] value buffer in which value of the status variable
needs to be filled in
@return status
@retval FALSE if variable is not found in the list
@retval TRUE if variable is found in the list
NOTE: Currently this function is implemented just to support 'bool' status
variables and 'long' status variables *only*. It can be extended very easily
for further show_types in future if required.
TODO: Currently show_status_arary switch case is tightly coupled with
pos, end, buff, value variables and also it stores the values in a 'table'.
Decouple the switch case to fill the buffer value so that it can be used
in show_status_array() and get_status_var() to avoid duplicate code.
*/
bool get_status_var(THD* thd, SHOW_VAR *list, const char * name, char * const value)
{
for (; list->name; list++)
{
int res= strcmp(list->name, name);
if (res == 0)
{
/*
if var->type is SHOW_FUNC, call the function.
Repeat as necessary, if new var is again SHOW_FUNC
*/
SHOW_VAR tmp;
for (; list->type == SHOW_FUNC; list= &tmp)
((mysql_show_var_func)(list->value))(thd, &tmp, value);
switch (list->type) {
case SHOW_BOOL:
strmov(value, *(bool*) list->value ? "ON" : "OFF");
break;
case SHOW_LONG:
int10_to_str(*(long*) list->value, value, 10);
break;
default:
/* not supported type */
DBUG_ASSERT(0);
}
return TRUE;
}
}
return FALSE;
}
/*
Removes an array of SHOW_VAR entries from the output of SHOW STATUS