From 9ef1ffa878533cdd4499eed717be60217fc96360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 2 May 2018 10:37:21 +0300 Subject: [PATCH] MXS-1507: Test transaction replay with switchover Added a test case that verifies that a successful transaction replay is performed when a master switchover is performed. --- maxscale-system-test/CMakeLists.txt | 4 + maxscale-system-test/mxs1507_migrate_trx.cpp | 90 ++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 maxscale-system-test/mxs1507_migrate_trx.cpp diff --git a/maxscale-system-test/CMakeLists.txt b/maxscale-system-test/CMakeLists.txt index 7b04c32b0..1dd9147e5 100644 --- a/maxscale-system-test/CMakeLists.txt +++ b/maxscale-system-test/CMakeLists.txt @@ -621,6 +621,10 @@ add_test_executable(mxs1507_trx_replay.cpp mxs1507_trx_replay mxs1507_trx_replay # https://jira.mariadb.org/browse/MXS-1507 add_test_executable(mxs1507_inconsistent_trx.cpp mxs1507_inconsistent_trx mxs1507_trx_replay LABELS readwritesplit REPL_BACKEND) +# MXS-1507: Transaction migration +# https://jira.mariadb.org/browse/MXS-1507 +add_test_executable(mxs1507_migrate_trx.cpp mxs1507_migrate_trx mxs1507_trx_replay LABELS readwritesplit REPL_BACKEND) + # MXS-1509: Show correct server state for multisource replication # https://jira.mariadb.org/browse/MXS-1509 add_test_executable(mxs1509.cpp mxs1509 mxs1509 LABELS mysqlmon REPL_BACKEND) diff --git a/maxscale-system-test/mxs1507_migrate_trx.cpp b/maxscale-system-test/mxs1507_migrate_trx.cpp new file mode 100644 index 000000000..ac73f948b --- /dev/null +++ b/maxscale-system-test/mxs1507_migrate_trx.cpp @@ -0,0 +1,90 @@ +/** + * MXS-1507: Test migration of transactions + * + * https://jira.mariadb.org/browse/MXS-1507 + */ +#include "testconnections.h" +#include +#include +#include + +using namespace std; + +int main(int argc, char** argv) +{ + Mariadb_nodes::require_gtid(true); + TestConnections test(argc, argv); + string master = "server1"; + string slave = "server2"; + + auto switchover = [&]() + { + test.maxscales->ssh_node_f(0, true, "maxctrl call command mariadbmon switchover MySQL-Monitor %s %s", + master.c_str(), slave.c_str()); + master.swap(slave); + sleep(5); // Seems that the system needs a few seconds to stabilize + }; + + auto query = [&](string q) + { + return execute_query_silent(test.maxscales->conn_rwsplit[0], q.c_str()) == 0; + }; + + auto ok = [&](string q) + { + test.assert(query(q), "Query '%s' should work: %s", q.c_str(), mysql_error(test.maxscales->conn_rwsplit[0])); + }; + + auto check = [&](string q) + { + ok("START TRANSACTION"); + Row row = get_row(test.maxscales->conn_rwsplit[0], q.c_str()); + ok("COMMIT"); + test.assert(!row.empty() && row[0] == "1", "Query should return 1: %s", q.c_str()); + }; + + // Create a table, insert a value and make sure it's replicated to all slaves + test.maxscales->connect(); + ok("CREATE OR REPLACE TABLE test.t1 (id INT)"); + ok("INSERT INTO test.t1 VALUES (1)"); + test.repl->connect(); + test.repl->sync_slaves(); + test.maxscales->disconnect(); + + cout << "Commit transaction" << endl; + test.maxscales->connect(); + ok("START TRANSACTION"); + ok("SELECT id FROM test.t1 WHERE id = 1 FOR UPDATE"); + switchover(); + ok("UPDATE test.t1 SET id = 2 WHERE id = 1"); + ok("COMMIT"); + check("SELECT COUNT(*) = 1 FROM t1 WHERE id = 2"); + + test.maxscales->disconnect(); + + cout << "Rollback transaction" << endl; + test.maxscales->connect(); + ok("START TRANSACTION"); + ok("UPDATE test.t1 SET id = 1"); + switchover(); + ok("ROLLBACK"); + check("SELECT COUNT(*) = 1 FROM t1 WHERE id = 2"); + test.maxscales->disconnect(); + + cout << "Read-only transaction" << endl; + test.maxscales->connect(); + ok("START TRANSACTION READ ONLY"); + ok("SELECT @@server_id"); // This causes a checksum mismatch if the transaction is migrated + switchover(); + ok("COMMIT"); + test.maxscales->disconnect(); + + test.maxscales->connect(); + ok("DROP TABLE test.t1"); + test.maxscales->disconnect(); + + // Even number of switchovers should bring us back to the original master + switchover(); + + return test.global_result; +}