Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
MXS-1751: Fix crash with available_when_donor=true
The `MYSQL_ROW row` variable was being overwritten by the extra query done
by the SST method detection code. Moving it into its own function prevents
this and makes the code significantly easier to comprehend.

Added a test case that reproduced the problem (MaxScale crashed) and
verifies that the patch fixes the problem.
  • Loading branch information
markus456 committed Mar 29, 2018
1 parent 01b0409 commit 6c2f064
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 28 deletions.
4 changes: 4 additions & 0 deletions maxscale-system-test/CMakeLists.txt
Expand Up @@ -621,6 +621,10 @@ add_test_executable(mxs1713_lots_of_databases.cpp mxs1713_lots_of_databases mxs1
# https://jira.mariadb.org/browse/MXS-1731
add_test_executable(mxs1731_old_persisted_config.cpp mxs1731_old_persisted_config replication LABELS REPL_BACKEND)

# MXS-1751: Maxscale crashes when certain config is in play (with nodes down)
# https://jira.mariadb.org/browse/MXS-1751
add_test_executable(mxs1751_available_when_donor_crash.cpp mxs1751_available_when_donor_crash mxs1751_available_when_donor_crash LABELS GALERA_BACKEND)

# 'namedserverfilter' test
add_test_executable(namedserverfilter.cpp namedserverfilter namedserverfilter LABELS namedserverfilter LIGHT REPL_BACKEND)

Expand Down
@@ -0,0 +1,53 @@
[maxscale]
threads=###threads###

[Galera Monitor]
type=monitor
module=galeramon
servers=server1,server2,server3
user=maxskysql
passwd=skysql
monitor_interval=100
available_when_donor=true

[RW Split Router]
type=service
router=readwritesplit
servers=server1,server2,server3
user=maxskysql
passwd=skysql
master_accept_reads=true

[RW Split Listener]
type=listener
service=RW Split Router
protocol=MySQLClient
port=4006

[CLI]
type=service
router=cli

[CLI Listener]
type=listener
service=CLI
protocol=maxscaled
socket=default

[server1]
type=server
address=###galera_server_IP_1###
port=###galera_server_port_1###
protocol=MySQLBackend

[server2]
type=server
address=###galera_server_IP_2###
port=###galera_server_port_2###
protocol=MySQLBackend

[server3]
type=server
address=###galera_server_IP_3###
port=###galera_server_port_3###
protocol=MySQLBackend
30 changes: 30 additions & 0 deletions maxscale-system-test/mxs1751_available_when_donor_crash.cpp
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
*
* Change Date: 2020-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/

#include "testconnections.h"

int main(int argc, char* argv[])
{
TestConnections test(argc, argv);

for (int i = 0; i < 2; i++)
{
test.galera->stop_node(0);
test.galera->stop_node(1);
test.galera->start_node(1);
test.galera->start_node(0);
test.galera->fix_replication();
}

return test.global_result;
}
69 changes: 41 additions & 28 deletions server/modules/monitor/galeramon/galeramon.c
Expand Up @@ -260,6 +260,41 @@ static json_t* diagnostics_json(const MXS_MONITOR *mon)
return rval;
}

static bool using_xtrabackup(MXS_MONITORED_SERVER *database, const char* server_string)
{
bool rval = false;
MYSQL_RES* result;

if (mxs_mysql_query(database->con, "SHOW VARIABLES LIKE 'wsrep_sst_method'") == 0
&& (result = mysql_store_result(database->con)) != NULL)
{
if (mysql_field_count(database->con) < 2)
{
mysql_free_result(result);
MXS_ERROR("Unexpected result for \"SHOW VARIABLES LIKE "
"'wsrep_sst_method'\". Expected 2 columns."
" MySQL Version: %s", server_string);
}

MYSQL_ROW row;

while ((row = mysql_fetch_row(result)))
{
if (row[1] && strncmp(row[1], "xtrabackup", 10) == 0)
{
rval = true;
}
}
mysql_free_result(result);
}
else
{
mon_report_query_error(database);
}

return rval;
}

/**
* Monitor an individual server. Does not deal with the setting of master or
* slave bits, except for clearing them when a server is not joined to the
Expand All @@ -273,8 +308,7 @@ monitorDatabase(MXS_MONITOR *mon, MXS_MONITORED_SERVER *database)
{
GALERA_MONITOR* handle = (GALERA_MONITOR*) mon->handle;
MYSQL_ROW row;
MYSQL_RES *result, *result2;
int isjoined = 0;
MYSQL_RES *result;
char *server_string;

/* Don't even probe server flagged as in maintenance */
Expand Down Expand Up @@ -364,40 +398,19 @@ monitorDatabase(MXS_MONITOR *mon, MXS_MONITORED_SERVER *database)
info.local_index = local_index;
}

ss_dassert(row[0] && row[1]);

if (strcmp(row[0], "wsrep_local_state") == 0)
{
if (strcmp(row[1], "4") == 0)
{
info.joined = 1;
}
/* Check if the node is a donor and is using xtrabackup, in this case it can stay alive */
else if (strcmp(row[1], "2") == 0 && handle->availableWhenDonor == 1)
else if (strcmp(row[1], "2") == 0 && handle->availableWhenDonor == 1 &&
using_xtrabackup(database, server_string))
{
if (mxs_mysql_query(database->con, "SHOW VARIABLES LIKE 'wsrep_sst_method'") == 0
&& (result2 = mysql_store_result(database->con)) != NULL)
{
if (mysql_field_count(database->con) < 2)
{
mysql_free_result(result);
mysql_free_result(result2);
MXS_ERROR("Unexpected result for \"SHOW VARIABLES LIKE "
"'wsrep_sst_method'\". Expected 2 columns."
" MySQL Version: %s", server_string);
return;
}
while ((row = mysql_fetch_row(result2)))
{
if (strncmp(row[1], "xtrabackup", 10) == 0)
{
info.joined = 1;
}
}
mysql_free_result(result2);
}
else
{
mon_report_query_error(database);
}
info.joined = 1;
}
else
{
Expand Down

0 comments on commit 6c2f064

Please sign in to comment.