diff --git a/maxscale-system-test/CMakeLists.txt b/maxscale-system-test/CMakeLists.txt index f2fc91d36..6e89cc389 100644 --- a/maxscale-system-test/CMakeLists.txt +++ b/maxscale-system-test/CMakeLists.txt @@ -954,6 +954,10 @@ add_test_executable(mxs1949_warn_user_injection.cpp mxs1949_warn_user_injection # https://jira.mariadb.org/browse/MXS-1958 add_test_executable(mxs1958_insert_priv.cpp mxs1958_insert_priv replication LABELS REPL_BACKEND) +# MXS-1961: Standalone master loses master status +# https://jira.mariadb.org/browse/MXS-1961 +add_test_executable(mxs1961_standalone_rejoin.cpp mxs1961_standalone_rejoin mxs1961_standalone_rejoin LABELS REPL_BACKEND) + configure_file(templates.h.in templates.h @ONLY) include(CTest) diff --git a/maxscale-system-test/cnf/maxscale.cnf.template.mxs1961_standalone_rejoin b/maxscale-system-test/cnf/maxscale.cnf.template.mxs1961_standalone_rejoin new file mode 100644 index 000000000..e9bcac12c --- /dev/null +++ b/maxscale-system-test/cnf/maxscale.cnf.template.mxs1961_standalone_rejoin @@ -0,0 +1,60 @@ +[maxscale] +threads=###threads### + +[MySQL-Monitor] +type=monitor +module=mysqlmon +servers= server1, server2, server3 +user=maxskysql +passwd= skysql +monitor_interval=1000 +detect_standalone_master=true +failcount=1 +allow_cluster_recovery=true +auto_failover=true +auto_rejoin=true +replication_user=repl +replication_password=repl +enforce_read_only_slaves=1 +verify_master_failure=false + +[RW Split Router] +type=service +router= readwritesplit +servers=server1, server2, server3 +user=maxskysql +passwd=skysql + +[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=###node_server_IP_1### +port=###node_server_port_1### +protocol=MySQLBackend + +[server2] +type=server +address=###node_server_IP_2### +port=###node_server_port_2### +protocol=MySQLBackend + +[server3] +type=server +address=###node_server_IP_3### +port=###node_server_port_3### +protocol=MySQLBackend diff --git a/maxscale-system-test/mxs1961_standalone_rejoin.cpp b/maxscale-system-test/mxs1961_standalone_rejoin.cpp new file mode 100644 index 000000000..1a06e8154 --- /dev/null +++ b/maxscale-system-test/mxs1961_standalone_rejoin.cpp @@ -0,0 +1,143 @@ +/** + * MXS-1961: Standalone master loses master status + */ + +#include "testconnections.h" +#include + +using namespace std; + +void checkpoint(TestConnections& test) +{ + const int v = 5; + test.maxscales->wait_for_monitor(v); + + for (auto&& s: {"server1", "server2", "server3"}) + { + auto status = test.get_server_status(s); + cout << s << " { "; + for (auto a: status) + { + cout << a << ", "; + } + cout << "}\n"; + } +} + +int main(int argc, char *argv[]) +{ + Mariadb_nodes::require_gtid(true); + TestConnections test(argc, argv); + + auto status = [&](const char* server) + { + return test.get_server_status(server); + }; + + auto comment = [&](const char* comment) + { + cout << comment << endl; + test.maxscales->ssh_node_f(0, true, "echo '----- %s -----' >> /var/log/maxscale/maxscale.log", comment); + }; + + auto slave = [&](const char* name) + { + static StringSet slave{"Slave", "Running"}; + test.assert(status(name) == slave, "'%s' should be a slave", name); + }; + + auto master = [&](const char* name) + { + static StringSet master{"Master", "Running"}; + test.assert(status(name) == master, "'%s' should be the master", name); + }; + + auto down = [&](const char* name) + { + static StringSet down{"Down"}; + test.assert(status(name) == down, "'%s' should be down", name); + }; + + auto block = [&](int node) + { + test.repl->block_node(node); + checkpoint(test); + }; + + auto unblock = [&](int node) + { + test.repl->unblock_node(node); + checkpoint(test); + }; + + test.maxscales->wait_for_monitor(1); + + master("server1"); + slave("server2"); + slave("server3"); + + comment("Blocking server1"); + block(0); + comment("Blocking server2"); + block(1); + + down("server1"); + down("server2"); + master("server3"); + + comment("Unblocking server2"); + unblock(1); + + down("server1"); + slave("server2"); + master("server3"); + + comment("Blocking server3"); + block(2); + comment("Unblocking server3"); + unblock(2); + + down("server1"); + master("server2"); + slave("server3"); + + comment("Blocking server3"); + block(2); + + down("server1"); + master("server2"); + down("server3"); + + comment("Unblocking server1"); + unblock(0); + + slave("server1"); + master("server2"); + down("server3"); + + comment("Blocking server2"); + block(1); + + master("server1"); + down("server2"); + down("server3"); + + comment("Unblocking server2"); + unblock(1); + + master("server1"); + slave("server2"); + down("server3"); + + comment("Unblocking server3"); + unblock(2); + + master("server1"); + slave("server2"); + slave("server3"); + + test.maxscales->stop(); + test.repl->fix_replication(); + + return test.global_result; +}