Remove obsolete tests
Removed the tests obsoleted by the sanity_check test case. This shortens the test time by about a minute and a half and removes about 2500 lines of code.
This commit is contained in:
parent
ee069ac45c
commit
80b23b428a
@ -61,7 +61,13 @@ add_test_executable(config_test.cpp config_test replication LABELS CONFIG)
|
||||
|
||||
add_subdirectory(cdc_datatypes)
|
||||
|
||||
# Routing sanity check
|
||||
# Routing sanity check. Also acts as the regression test case the following issues:
|
||||
#
|
||||
# MXS-127
|
||||
# MXS-47
|
||||
# MXS-682
|
||||
# MXS-957
|
||||
# MXS-1786
|
||||
add_test_executable(sanity_check.cpp sanity_check replication LABELS LIGHT REPL_BACKEND)
|
||||
|
||||
# Repeatedly connect to maxscale while the backends reject all connections, expect no crash
|
||||
@ -70,15 +76,9 @@ add_test_executable(backend_auth_fail.cpp backend_auth_fail replication LABELS r
|
||||
# Regression case for the bug "MaxScale ignores host in user authentication"
|
||||
add_test_executable(bug143.cpp bug143 replication LABELS MySQLAuth REPL_BACKEND)
|
||||
|
||||
# Regression case for the bug "Executing '\s' doesn't always produce complete result set"
|
||||
add_test_executable(bug422.cpp bug422 replication LABELS readwritesplit readconnroute maxscale REPL_BACKEND)
|
||||
|
||||
# Regression case for the bug "Wildcard in host column of mysql.user table don't work properly"
|
||||
add_test_executable(bug448.cpp bug448 replication LABELS MySQLAuth LIGHT REPL_BACKEND)
|
||||
|
||||
# Regression case for the bug "rwsplit counts every connection twice in master - counnection counts leak"
|
||||
add_test_executable(bug469.cpp bug469 replication LABELS readwritesplit LIGHT REPL_BACKEND)
|
||||
|
||||
# Regression case for the bug "Routing Hints route to server sometimes doesn't work"
|
||||
add_test_executable(bug471.cpp bug471 bug471 LABELS readwritesplit hintfilter REPL_BACKEND)
|
||||
|
||||
@ -88,15 +88,6 @@ add_test_executable(bug473.cpp bug473 hints LABELS readwritesplit hintfilter REP
|
||||
# Regression case for the bug "The end comment tag in hints isn't properly detected"
|
||||
add_test_executable(bug475.cpp bug475 hints LABELS readwritesplit hintfilter REPL_BACKEND)
|
||||
|
||||
# Regression case for the bug "SHOW VARIABLES randomly failing with "Lost connection to MySQL server"
|
||||
add_test_executable(bug488.cpp bug488 galera LABELS readwritesplit readconnroute maxscale GALERA_BACKEND)
|
||||
|
||||
# Regression case for the bug "rw-split router does not send last_insert_id() to master"
|
||||
add_test_executable(bug507.cpp bug507 replication LABELS readwritesplit LIGHT REPL_BACKEND)
|
||||
|
||||
# Regression case for the bug "Referring to a nonexisting server in servers=... doesn't even raise a warning"
|
||||
add_test_executable(bug509.cpp bug509 galera LABELS readwritesplit GALERA_BACKEND)
|
||||
|
||||
# Checks "SELECT * INTO OUTFILE" and "LOAD DATA LOCAL INFILE"
|
||||
add_test_executable(bug519.cpp bug519 replication LABELS readwritesplit REPL_BACKEND)
|
||||
|
||||
@ -151,9 +142,6 @@ add_test_executable(bug620.cpp bug620 bug620 LABELS MySQLAuth MySQLProtocol REPL
|
||||
# Regression case for the bug "Crash when user define with old password style (before 4.1 protocol)"
|
||||
add_test_executable(bug626.cpp bug626 replication LABELS MySQLAuth MySQLProtocol REPL_BACKEND)
|
||||
|
||||
# Regression case for the bug 634 "SHOW SLAVE STATUS in RW SPLITTER is send to master"
|
||||
add_test_executable(bug634.cpp bug634 replication LABELS readwritesplit REPL_BACKEND)
|
||||
|
||||
# Regression cases for several TEE filter hangs
|
||||
#add_test_executable(bug645.cpp bug645 bug645 LABELS tee REPL_BACKEND)
|
||||
#add_test_executable(bug645_1.cpp bug645_1 bug645_1 LABELS tee REPL_BACKEND)
|
||||
@ -190,18 +178,9 @@ add_test_executable(bug673.cpp bug673 bug673 LABELS MySQLAuth REPL_BACKEND)
|
||||
# Crash in case of backend node in Galera cluster stopping and then reconnect to Maxscale
|
||||
add_test_executable(bug676.cpp bug676 galera LABELS galeramon GALERA_BACKEND)
|
||||
|
||||
# Rgression test for th bug "RWSplit: 'SELECT @a:=@a+1 as a, test.b FROM test' breaks client session"
|
||||
add_test_executable(bug694.cpp bug694 bug694 LABELS readwritesplit REPL_BACKEND)
|
||||
|
||||
# Compare @@hostname from "select @@wsrep_node_name, @@hostname" and from "select @@hostname, @@wsrep_node_name"
|
||||
add_test_executable(bug699.cpp bug699 galera LABELS readwritesplit LIGHT GALERA_BACKEND)
|
||||
|
||||
# Wrong processing of 'SET GLOBAL sql_mode="ANSI"'
|
||||
add_test_executable(bug705.cpp bug705 bug705 LABELS MySQLAuth REPL_BACKEND)
|
||||
|
||||
# Try SHOW GLOBAL STATUS via Maxscale
|
||||
add_test_executable(bug711.cpp bug711 bug711 LABELS readwritesplit REPL_BACKEND)
|
||||
|
||||
# Prepared statement from PHP application
|
||||
add_test_executable(bug729.cpp bug729 replication LABELS readwritesplit LIGHT REPL_BACKEND)
|
||||
|
||||
@ -392,9 +371,6 @@ add_test_executable(mm.cpp mm mm LABELS mmmon BREAKS_REPL)
|
||||
# Regression case for the bug "Two monitors loaded at the same time result into not working installation"
|
||||
add_test_executable(mxs118.cpp mxs118 mxs118 LABELS maxscale LIGHT REPL_BACKEND)
|
||||
|
||||
# Regression case for the bug "disable_sescmd_history causes MaxScale to crash under load"
|
||||
add_test_executable(mxs127.cpp mxs127 mxs127 LABELS readwritesplit LIGHT REPL_BACKEND)
|
||||
|
||||
# Prepearing and execution statements in the loop
|
||||
add_test_executable(mxs244_prepared_stmt_loop.cpp mxs244_prepared_stmt_loop galera LABELS readwritesplit readconnroute LIGHT GALERA_BACKEND)
|
||||
|
||||
@ -435,9 +411,6 @@ add_test_derived(mxs37_table_privilege_galera mxs37_table_privilege galera LABEL
|
||||
# Connect repeatedly to Schema router and execute simple query, check if auth is ok
|
||||
add_test_executable(mxs431.cpp mxs431 sharding LABELS schemarouter REPL_BACKEND BREAKS_REPL)
|
||||
|
||||
# execute SELECT REPEAT('a',i), where 'i' is changing from 1 to 50000 (bug "Session freeze when small tail packet")
|
||||
add_test_executable(mxs47.cpp mxs47 replication LABELS MySQLProtocol LIGHT REPL_BACKEND)
|
||||
|
||||
# Regression case for the bug "USE <db> hangs when Tee filter uses matching"
|
||||
#add_test_executable(mxs501_tee_usedb.cpp mxs501_tee_usedb mxs501 LABELS tee REPL_BACKEND)
|
||||
|
||||
@ -463,12 +436,6 @@ add_test_executable(mxs621_unreadable_cnf.cpp mxs621_unreadable_cnf replication
|
||||
add_test_executable(mxs657_restart.cpp mxs657_restart replication LABELS maxscale HEAVY REPL_BACKEND)
|
||||
add_test_executable(mxs657_restart_service.cpp mxs657_restart_service replication LABELS maxscale REPL_BACKEND)
|
||||
|
||||
# put cyrillic letters to the table and check from backend
|
||||
add_test_executable(mxs682_cyrillic.cpp mxs682_cyrillic replication LABELS maxscale LIGHT REPL_BACKEND)
|
||||
|
||||
# put cyrillic letters to the table and check from backend (Galera backend)
|
||||
add_test_derived(mxs682_cyrillic_galera mxs682_cyrillic galera LABELS maxscale GALERA_BACKEND)
|
||||
|
||||
# Connect using different default database using user with database and table level grants
|
||||
add_test_executable(mxs716.cpp mxs716 replication LABELS MySQLAuth LIGHT REPL_BACKEND)
|
||||
|
||||
@ -554,9 +521,6 @@ add_test_executable(cache_runtime_ttl.cpp cache_runtime_ttl cache_runtime_ttl LA
|
||||
# Set utf8mb4 in the backend and restart Maxscale
|
||||
add_test_executable(mxs951_utfmb4.cpp mxs951_utfmb4 replication LABELS REPL_BACKEND)
|
||||
|
||||
# Execute given SQL through readwritesplit (with temporary tables usage)
|
||||
add_test_executable(mxs957.cpp mxs957 replication LABELS readwritesplit REPL_BACKEND)
|
||||
|
||||
# Regression case for the bug "Defunct processes after maxscale have executed script during failover"
|
||||
add_test_executable(mxs1045.cpp mxs1045 mxs1045 LABELS maxscale REPL_BACKEND)
|
||||
|
||||
@ -704,10 +668,6 @@ add_test_executable(mxs1776_ps_exec_hang.cpp mxs1776_ps_exec_hang replication LA
|
||||
# https://jira.mariadb.org/browse/MXS-1776
|
||||
add_test_executable(mxs1778_causal_reads.cpp mxs1778_causal_reads mxs1778_causal_reads LABELS readwritesplit REPL_BACKEND)
|
||||
|
||||
# MXS-1786: Hang with COM_STATISTICS
|
||||
# https://jira.mariadb.org/browse/MXS-1786
|
||||
add_test_executable(mxs1786_statistics.cpp mxs1786_statistics replication LABELS readwritesplit REPL_BACKEND)
|
||||
|
||||
# MXS-1787: Crash with PS: CALL p1((SELECT f1()), ?)
|
||||
# https://jira.mariadb.org/browse/MXS-1787
|
||||
add_test_executable(mxs1787_call_ps.cpp mxs1787_call_ps replication LABELS readwritesplit REPL_BACKEND)
|
||||
@ -805,14 +765,6 @@ add_test_executable(rwsplit_readonly_stress.cpp rwsplit_readonly_stress rwsplit_
|
||||
# Test readwritesplit multi-statement handling
|
||||
add_test_executable(rwsplit_multi_stmt.cpp rwsplit_multi_stmt rwsplit_multi_stmt LABELS readwritesplit REPL_BACKEND)
|
||||
|
||||
# Test readwritesplit multi-statement handling
|
||||
add_test_executable(rwsplit_read_only_trx.cpp rwsplit_read_only_trx rwsplit_read_only_trx LABELS readwritesplit REPL_BACKEND)
|
||||
|
||||
# Test replication-manager with MaxScale
|
||||
#add_test_executable(replication_manager.cpp replication_manager replication_manager LABELS maxscale REPL_BACKEND)
|
||||
#add_test_executable_notest(replication_manager_2nodes.cpp replication_manager_2nodes replication_manager_2nodes LABELS maxscale REPL_BACKEND)
|
||||
#add_test_executable_notest(replication_manager_3nodes.cpp replication_manager_3nodes replication_manager_3nodes LABELS maxscale REPL_BACKEND)
|
||||
|
||||
# Schemarouter duplicate database detection test: create DB on all nodes and then try query againt schema router
|
||||
add_test_executable(schemarouter_duplicate.cpp schemarouter_duplicate schemarouter_duplicate LABELS schemarouter REPL_BACKEND)
|
||||
|
||||
|
@ -1,126 +0,0 @@
|
||||
/**
|
||||
* @file bug422.cpp bug422 regression case ( Executing '\s' doesn't always produce complete result set)
|
||||
*
|
||||
* Test executes "show status" 1000 times against all Maxscale services and checks Maxscale is alive after it.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Vilho Raatikka 2014-04-15 07:03:03 UTC
|
||||
* Read/write split router
|
||||
* -------------------------
|
||||
*
|
||||
* Login to MaxScale & read/write split router, for example
|
||||
*
|
||||
* mysql --host=127.0.0.1 -P 4006 -u maxuser -pmaxpwd
|
||||
*
|
||||
* Complete result :
|
||||
*
|
||||
* MySQL [(none)]> \s
|
||||
* --------------
|
||||
* mysql Ver 15.1 Distrib 5.5.33-MariaDB, for Linux (x86_64) using readline 5.1
|
||||
*
|
||||
* Connection id: 4051
|
||||
* Current database:
|
||||
* Current user: maxuser@localhost
|
||||
* SSL: Not in use
|
||||
* Current pager: less
|
||||
* Using outfile: ''
|
||||
* Using delimiter: ;
|
||||
* Server: MySQL
|
||||
* Server version: MaxScale 0.5.0 Source distribution
|
||||
* Protocol version: 10
|
||||
* Connection: 127.0.0.1 via TCP/IP
|
||||
* Server characterset: latin1
|
||||
* Db characterset: latin1
|
||||
* Client characterset: latin1
|
||||
* Conn. characterset: latin1
|
||||
* TCP port: 4006
|
||||
* Uptime: 34 min 23 sec
|
||||
*
|
||||
* Threads: 5 Questions: 206 Slow queries: 0 Opens: 0 Flush tables: 2 Open tables: 26 Queries per
|
||||
* second avg: 0.099
|
||||
* --------------
|
||||
*
|
||||
*
|
||||
* By running same a few time in a row, an incomplete result set arrives, like the following:
|
||||
*
|
||||
* MySQL [(none)]> \s
|
||||
* --------------
|
||||
* mysql Ver 15.1 Distrib 5.5.33-MariaDB, for Linux (x86_64) using readline 5.1
|
||||
*
|
||||
* Connection id: 4051
|
||||
* Current database:
|
||||
* Current user: maxuser@localhost
|
||||
* SSL: Not in use
|
||||
* Current pager: less
|
||||
* Using outfile: ''
|
||||
* Using delimiter: ;
|
||||
* Server: MySQL
|
||||
* Server version: MaxScale 0.5.0 Source distribution
|
||||
* Protocol version: 10
|
||||
* Connection: 127.0.0.1 via TCP/IP
|
||||
* Server characterset: latin1
|
||||
* Db characterset: latin1
|
||||
* Client characterset: latin1
|
||||
* Conn. characterset: latin1
|
||||
* TCP port: 4006
|
||||
* --------------
|
||||
*
|
||||
* MySQL [(none)]>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include "testconnections.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConnections* Test = new TestConnections(argc, argv);
|
||||
int i;
|
||||
int iterations = 1000;
|
||||
if (Test->smoke)
|
||||
{
|
||||
iterations = 100;
|
||||
}
|
||||
|
||||
Test->set_timeout(10);
|
||||
|
||||
Test->tprintf("Connecting to all MaxScale services\n");
|
||||
Test->add_result(Test->maxscales->connect_maxscale(0), "Can not connect to Maxscale\n");
|
||||
|
||||
Test->tprintf("executing show status %d times\n", iterations);
|
||||
|
||||
|
||||
for (i = 0; i < iterations; i++)
|
||||
{
|
||||
Test->set_timeout(5);
|
||||
Test->add_result(execute_query(Test->maxscales->conn_rwsplit[0], (char*) "show status"),
|
||||
"Query %d agains RWSplit failed\n",
|
||||
i);
|
||||
}
|
||||
for (i = 0; i < iterations; i++)
|
||||
{
|
||||
Test->set_timeout(5);
|
||||
Test->add_result(execute_query(Test->maxscales->conn_slave[0], (char*) "show status"),
|
||||
"Query %d agains ReadConn Slave failed\n",
|
||||
i);
|
||||
}
|
||||
for (i = 0; i < iterations; i++)
|
||||
{
|
||||
Test->set_timeout(5);
|
||||
Test->add_result(execute_query(Test->maxscales->conn_master[0], (char*) "show status"),
|
||||
"Query %d agains ReadConn Master failed\n",
|
||||
i);
|
||||
}
|
||||
Test->set_timeout(10);
|
||||
|
||||
Test->maxscales->close_maxscale_connections(0);
|
||||
Test->check_maxscale_alive(0);
|
||||
int rval = Test->global_result;
|
||||
delete Test;
|
||||
return rval;
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
/**
|
||||
* @file bug469 bug469 regression test case ("rwsplit counts every connection twice in master - counnection
|
||||
* counts leak")
|
||||
* - use maxadmin command "show server server1" and check "Current no. of conns" and "Number of connections" -
|
||||
* both should be 0
|
||||
* - execute simple query against RWSplit
|
||||
* - use maxadmin command "show server server1" and check "Current no. of conns" (should be 0) and "Number of
|
||||
* connections" (should be 1)
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Vilho Raatikka 2014-08-05 12:28:21 UTC
|
||||
* Every connection is counted twice in master and decremented only once. As a result master seems always to
|
||||
* have active connections after first connection is established.
|
||||
*
|
||||
* Server 0x21706e0 (server1)
|
||||
* Server: 127.0.0.1
|
||||
* Status: Master, Running
|
||||
* Protocol: MySQLBackend
|
||||
* Port: 3000
|
||||
* Server Version: 5.5.37-MariaDB-debug-log
|
||||
* Node Id: 3000
|
||||
* Master Id: -1
|
||||
* Slave Ids: 3001, 3002 , 3003
|
||||
* Repl Depth: 0
|
||||
* Number of connections: 6
|
||||
* Current no. of conns: 3
|
||||
* Current no. of operations: 0
|
||||
* Server 0x21705e0 (server2)
|
||||
* Server: 127.0.0.1
|
||||
* Status: Slave, Running
|
||||
* Protocol: MySQLBackend
|
||||
* Port: 3001
|
||||
* Server Version: 5.5.37-MariaDB-debug-log
|
||||
* Node Id: 3001
|
||||
* Master Id: 3000
|
||||
* Slave Ids:
|
||||
* Repl Depth: 1
|
||||
* Number of connections: 3
|
||||
* Current no. of conns: 0
|
||||
* Current no. of operations: 0
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include "testconnections.h"
|
||||
#include "maxadmin_operations.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConnections* Test = new TestConnections(argc, argv);
|
||||
char res[1024];
|
||||
int res_d;
|
||||
Test->set_timeout(10);
|
||||
|
||||
Test->maxscales->get_maxadmin_param(0,
|
||||
(char*) "show server server1",
|
||||
(char*) "Current no. of conns:",
|
||||
res);
|
||||
sscanf(res, "%d", &res_d);
|
||||
Test->tprintf("Before: Current num of conn %d\n", res_d);
|
||||
Test->add_result(res_d, "curr num of conn is not 0\n");
|
||||
Test->maxscales->get_maxadmin_param(0,
|
||||
(char*) "show server server1",
|
||||
(char*) "Number of connections:",
|
||||
res);
|
||||
sscanf(res, "%d", &res_d);
|
||||
Test->tprintf("Before: num of conn %d\n", res_d);
|
||||
Test->add_result(res_d, "num of conn is not 0");
|
||||
|
||||
Test->maxscales->connect_rwsplit(0);
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0], (char*) "select 1");
|
||||
Test->maxscales->close_rwsplit(0);
|
||||
|
||||
Test->stop_timeout();
|
||||
sleep(10);
|
||||
|
||||
Test->set_timeout(10);
|
||||
|
||||
Test->maxscales->get_maxadmin_param(0,
|
||||
(char*) "show server server1",
|
||||
(char*) "Current no. of conns:",
|
||||
res);
|
||||
sscanf(res, "%d", &res_d);
|
||||
Test->tprintf("After: Current num of conn %d\n", res_d);
|
||||
Test->add_result(res_d, "curr num of conn is not 0\n");
|
||||
Test->maxscales->get_maxadmin_param(0,
|
||||
(char*) "show server server1",
|
||||
(char*) "Number of connections:",
|
||||
res);
|
||||
sscanf(res, "%d", &res_d);
|
||||
Test->tprintf("After: num of conn %d\n", res_d);
|
||||
if (res_d != 1)
|
||||
{
|
||||
Test->add_result(1, "num of conn is not 1");
|
||||
}
|
||||
|
||||
Test->check_maxscale_alive(0);
|
||||
|
||||
int rval = Test->global_result;
|
||||
delete Test;
|
||||
return rval;
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
/**
|
||||
* @file bug488.cpp regression case for bug 488 ("SHOW VARIABLES randomly failing with "Lost connection to
|
||||
* MySQL server")
|
||||
*
|
||||
* - try "SHOW VARIABLES;" 100 times against all Maxscale services
|
||||
* First round: 100 iterations for RWSplit, then ReadConn Master, then ReadConn Slave
|
||||
* Second round: 100 iteration and in every iterations all three Maxscale services are in use.
|
||||
* - check if Maxscale is alive.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Kolbe Kegel 2014-08-27 18:37:14 UTC
|
||||
* Created attachment 138 [details]
|
||||
* good.txt and bad.txt
|
||||
*
|
||||
* Sending "SHOW VARIABLES" to MaxScale seems to sometimes result in "ERROR 2013 (HY000) at line 1: Lost
|
||||
* connection to MySQL server during query". It appears to be random. It seems to be sending the query to the
|
||||
* same backend server, so I'm not sure what is happening. I'm including the debug log for both the "good" and
|
||||
* "bad" queries.
|
||||
* Comment 1 Vilho Raatikka 2014-08-27 18:41:25 UTC
|
||||
* Seems to happen exactly every second time with rwsplit router. Didn't experience it with read connection
|
||||
* router.
|
||||
* Comment 2 Kolbe Kegel 2014-08-27 18:47:13 UTC
|
||||
* Not exactly every 2nd time.
|
||||
*
|
||||
* $ mysql -h max1 -P 4006 -u maxuser -pmaxpwd -e 'show variables' >/dev/null
|
||||
* $ mysql -h max1 -P 4006 -u maxuser -pmaxpwd -e 'show variables' >/dev/null
|
||||
* $ mysql -h max1 -P 4006 -u maxuser -pmaxpwd -e 'show variables' >/dev/null
|
||||
* ERROR 2013 (HY000) at line 1: Lost connection to MySQL server during query
|
||||
* $ mysql -h max1 -P 4006 -u maxuser -pmaxpwd -e 'show variables' >/dev/null
|
||||
* ERROR 2013 (HY000) at line 1: Lost connection to MySQL server during query
|
||||
* $ mysql -h max1 -P 4006 -u maxuser -pmaxpwd -e 'show variables' >/dev/null
|
||||
* $ mysql -h max1 -P 4006 -u maxuser -pmaxpwd -e 'show variables' >/dev/null
|
||||
* ERROR 2013 (HY000) at line 1: Lost connection to MySQL server during query
|
||||
* $ mysql -h max1 -P 4006 -u maxuser -pmaxpwd -e 'show variables' >/dev/null
|
||||
* ERROR 2013 (HY000) at line 1: Lost connection to MySQL server during query
|
||||
* $ mysql -h max1 -P 4006 -u maxuser -pmaxpwd -e 'show variables' >/dev/null
|
||||
* ERROR 2013 (HY000) at line 1: Lost connection to MySQL server during query
|
||||
* Comment 3 Vilho Raatikka 2014-08-28 10:48:39 UTC
|
||||
* SHOW VARIABLES is session write command - which is unnecessary because those could be read from any server
|
||||
* - and what causes client to return 'lost connection' message to the user is duplicated response packet from
|
||||
* MaxScale to the client.
|
||||
*
|
||||
* SHOW VARIABLES response should start like this:
|
||||
* T 127.0.0.1:59776 -> 127.0.0.1:4006 [AP]
|
||||
* 0f 00 00 00 03 73 68 6f 77 20 76 61 72 69 61 62 .....show variab
|
||||
* 6c 65 73 les
|
||||
*
|
||||
* T 127.0.0.1:4006 -> 127.0.0.1:59776 [AP]
|
||||
* 01 00 00 01 02 .....
|
||||
*
|
||||
* T 127.0.0.1:4006 -> 127.0.0.1:59776 [AP]
|
||||
* 54 00 00 02 03 64 65 66 12 69 6e 66 6f 72 6d 61 T....def.informa
|
||||
* 74 69 6f 6e 5f 73 63 68 65 6d 61 09 56 41 52 49 tion_schema.VARI
|
||||
* 41 42 4c 45 53 09 56 41 52 49 41 42 4c 45 53 0d ABLES.VARIABLES.
|
||||
* 56 61 72 69 61 62 6c 65 5f 6e 61 6d 65 0d 56 41 Variable_name.VA
|
||||
* 52 49 41 42 4c 45 5f 4e 41 4d 45 0c 08 00 40 00 RIABLE_NAME...@.
|
||||
* 00 00 fd 01 00 00 00 00 ........
|
||||
*
|
||||
* While in the failing case the initial packet is followed something like this:
|
||||
*
|
||||
* T 127.0.0.1:59776 -> 127.0.0.1:4006 [AP]
|
||||
* 0f 00 00 00 03 73 68 6f 77 20 76 61 72 69 61 62 .....show variab
|
||||
* 6c 65 73 les
|
||||
*
|
||||
* T 127.0.0.1:4006 -> 127.0.0.1:59776 [AP]
|
||||
* 1d 00 00 d5 18 69 6e 6e 6f 64 62 5f 75 73 65 5f .....innodb_use_
|
||||
* 61 74 6f 6d 69 63 5f 77 72 69 74 65 73 03 4f 46 atomic_writes.OF
|
||||
* 46 F
|
||||
*
|
||||
* T 127.0.0.1:4006 -> 127.0.0.1:59776 [AP]
|
||||
* 19 00 00 d6 14 69 6e 6e 6f 64 62 5f 75 73 65 5f .....innodb_use_
|
||||
* 66 61 6c 6c 6f 63 61 74 65 03 4f 46 46 fallocate.OFF
|
||||
*
|
||||
* - where those innodb related packets are duplicates from the previous response.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include "testconnections.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConnections* Test = new TestConnections(argc, argv);
|
||||
Test->set_timeout(10);
|
||||
int i;
|
||||
|
||||
Test->repl->connect();
|
||||
Test->maxscales->connect_maxscale(0);
|
||||
|
||||
Test->tprintf("Trying SHOW VARIABLES to different Maxscale services\n");
|
||||
fflush(stdout);
|
||||
Test->tprintf("RWSplit\n");
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
Test->set_timeout(5);
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0], (char*) "SHOW VARIABLES;");
|
||||
}
|
||||
Test->tprintf("ReadConn master\n");
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
Test->set_timeout(5);
|
||||
Test->try_query(Test->maxscales->conn_master[0], (char*) "SHOW VARIABLES;");
|
||||
}
|
||||
Test->tprintf("ReadConn slave\n");
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
Test->set_timeout(5);
|
||||
Test->try_query(Test->maxscales->conn_slave[0], (char*) "SHOW VARIABLES;");
|
||||
}
|
||||
|
||||
Test->tprintf("All in one loop\n");
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
Test->set_timeout(5);
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0], (char*) "SHOW VARIABLES;");
|
||||
Test->try_query(Test->maxscales->conn_master[0], (char*) "SHOW VARIABLES;");
|
||||
Test->try_query(Test->maxscales->conn_slave[0], (char*) "SHOW VARIABLES;");
|
||||
}
|
||||
|
||||
Test->set_timeout(10);
|
||||
Test->maxscales->close_maxscale_connections(0);
|
||||
Test->repl->close_connections();
|
||||
|
||||
Test->check_maxscale_alive(0);
|
||||
|
||||
int rval = Test->global_result;
|
||||
delete Test;
|
||||
return rval;
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
/**
|
||||
* @file bug507.cpp regression case for bug 507 ( "rw-split router does not send last_insert_id() to master" )
|
||||
*
|
||||
* - "CREATE TABLE t2 (id INT(10) NOT NULL AUTO_INCREMENT, x int, PRIMARY KEY (id));",
|
||||
* - do INSERT using RWsplit
|
||||
* - do "select last_insert_id(), @@server_id" using RWSplit and directly to Master, compare @@server_id
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Kolbe Kegel 2014-09-01 14:45:56 UTC
|
||||
* After inserting a row via the rw-split router, a call to last_insert_id() can go to a slave, producing bad
|
||||
* results.
|
||||
*
|
||||
* mariadb> select * from t1;
|
||||
+----+
|
||||
| id |
|
||||
+----+
|
||||
| 1 |
|
||||
| 4 |
|
||||
+----+
|
||||
| 2 rows in set (0.00 sec)
|
||||
|
|
||||
| mariadb> insert into t1 values ();
|
||||
| Query OK, 1 row affected (0.00 sec)
|
||||
|
|
||||
| mariadb> select * from t1;
|
||||
+----+
|
||||
| id |
|
||||
+----+
|
||||
| 1 |
|
||||
| 4 |
|
||||
| 7 |
|
||||
+----+
|
||||
| 3 rows in set (0.00 sec)
|
||||
|
|
||||
| mariadb> select last_insert_id();
|
||||
+------------------+
|
||||
| last_insert_id() |
|
||||
+------------------+
|
||||
| 0 |
|
||||
+------------------+
|
||||
| 1 row in set (0.00 sec)
|
||||
|
|
||||
| mariadb> select @@wsrep_node_address, last_insert_id();
|
||||
+----------------------+------------------+
|
||||
| @@wsrep_node_address | last_insert_id() |
|
||||
+----------------------+------------------+
|
||||
| 192.168.30.31 | 7 |
|
||||
+----------------------+------------------+
|
||||
| 1 row in set (0.00 sec)
|
||||
| Comment 1 Vilho Raatikka 2014-09-01 17:51:45 UTC
|
||||
| last_inserted_id() belongs to UNKNOWN_FUNC class to which many read-only system functions belong too. Thus
|
||||
|last_inserted_id() was routed to any slave.
|
||||
|
|
||||
| Unfortunately I can't confirm wrong behavior since running the same sequence generates same output when
|
||||
|connected directly to MariaDB backend. Perhaps there is something required for the table t1 which is not
|
||||
|included here?
|
||||
| Comment 2 Vilho Raatikka 2014-09-01 20:01:35 UTC
|
||||
| An autoincrement attribute was missing.
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include "testconnections.h"
|
||||
|
||||
const char* sel1 = "select last_insert_id(), @@server_id";
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConnections* Test = new TestConnections(argc, argv);
|
||||
Test->set_timeout(60);
|
||||
|
||||
Test->repl->connect();
|
||||
Test->maxscales->connect_maxscale(0);
|
||||
|
||||
if (Test->repl->N < 3)
|
||||
{
|
||||
Test->tprintf("There is not enoght nodes for test\n");
|
||||
delete Test;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Test->tprintf("Creating table\n");
|
||||
fflush(stdout);
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0], (char*) "DROP TABLE IF EXISTS t2");
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0],
|
||||
(char*) "CREATE TABLE t2 (id INT(10) NOT NULL AUTO_INCREMENT, x int, PRIMARY KEY (id));");
|
||||
Test->tprintf("Doing INSERTs\n");
|
||||
fflush(stdout);
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0], (char*) "insert into t2 (x) values (1);");
|
||||
|
||||
Test->stop_timeout();
|
||||
Test->repl->sync_slaves();
|
||||
|
||||
Test->set_timeout(20);
|
||||
Test->tprintf("Trying \n");
|
||||
char last_insert_id1[1024];
|
||||
char last_insert_id2[1024];
|
||||
if ((
|
||||
find_field(Test->maxscales->conn_rwsplit[0],
|
||||
sel1,
|
||||
"@@server_id",
|
||||
&last_insert_id1[0])
|
||||
!= 0 ) || (
|
||||
find_field(Test->repl->nodes[0],
|
||||
sel1,
|
||||
"@@server_id",
|
||||
&last_insert_id2[0])
|
||||
!= 0 ))
|
||||
{
|
||||
Test->tprintf("@@server_id fied not found!!\n");
|
||||
delete Test;
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Test->tprintf("'%s' to RWSplit gave @@server_id %s\n", sel1, last_insert_id1);
|
||||
Test->tprintf("'%s' directly to master gave @@server_id %s\n", sel1, last_insert_id2);
|
||||
Test->add_result(strcmp(last_insert_id1, last_insert_id2),
|
||||
"last_insert_id() are different depending in which order terms are in SELECT\n");
|
||||
}
|
||||
|
||||
Test->maxscales->close_maxscale_connections(0);
|
||||
Test->repl->close_connections();
|
||||
|
||||
Test->check_maxscale_alive(0);
|
||||
|
||||
int rval = Test->global_result;
|
||||
delete Test;
|
||||
return rval;
|
||||
}
|
@ -1,153 +0,0 @@
|
||||
/**
|
||||
* @file bug509.cpp regression case for bug 509 and 507 ( "Referring to a nonexisting server in servers=...
|
||||
* doesn't even raise a warning"
|
||||
* and "rw-split router does not send last_insert_id() to master" )
|
||||
*
|
||||
* - "CREATE TABLE t2 (id INT(10) NOT NULL AUTO_INCREMENT, x int, PRIMARY KEY (id));",
|
||||
* - do a number of INSERTs first using RWsplit, then directly Galera nodes.
|
||||
* - do "select @@wsrep_node_address, last_insert_id();" and "select last_insert_id(), @@wsrep_node_address;"
|
||||
* and compares results.
|
||||
* - do "insert into t2 (x) values (i);" 1000 times and compares results of
|
||||
* "select @@wsrep_node_address, last_insert_id();" and "select last_insert_id(), @@wsrep_node_address;"
|
||||
*
|
||||
* Test fails if results are different (after 5 seconds of waiting after last INSERT)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Kolbe Kegel 2014-09-01 14:48:12 UTC
|
||||
* For some reason, the order of terms in the field list of a SELECT statement influences how the rw-split
|
||||
* router decides where to send a statement.
|
||||
*
|
||||
* mariadb> select @@wsrep_node_address, last_insert_id();
|
||||
+----------------------+------------------+
|
||||
| @@wsrep_node_address | last_insert_id() |
|
||||
+----------------------+------------------+
|
||||
| 192.168.30.31 | 7 |
|
||||
+----------------------+------------------+
|
||||
| 1 row in set (0.00 sec)
|
||||
|
|
||||
| mariadb> select last_insert_id(), @@wsrep_node_address;
|
||||
+------------------+----------------------+
|
||||
| last_insert_id() | @@wsrep_node_address |
|
||||
+------------------+----------------------+
|
||||
| 0 | 192.168.30.33 |
|
||||
+------------------+----------------------+
|
||||
| 1 row in set (0.00 sec)
|
||||
| Comment 1 Vilho Raatikka 2014-09-03 20:44:17 UTC
|
||||
| Added code to detect last_insert_id() function and now both types of elements are routed to master and
|
||||
|their order of appearance doesn't matter.
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include "testconnections.h"
|
||||
|
||||
const char* sel1 = "select @@wsrep_node_address, last_insert_id();";
|
||||
const char* sel2 = "select last_insert_id(), @@wsrep_node_address;";
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConnections* Test = new TestConnections(argc, argv);
|
||||
Test->set_timeout(60);
|
||||
|
||||
Test->galera->connect();
|
||||
Test->maxscales->connect_maxscale(0);
|
||||
|
||||
if (Test->galera->N < 3)
|
||||
{
|
||||
Test->tprintf("There is not enoght nodes for test\n");
|
||||
delete Test;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Test->tprintf("Creating table\n");
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0], (char*) "DROP TABLE IF EXISTS t2;");
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0],
|
||||
(char*) "CREATE TABLE t2 (id INT(10) NOT NULL AUTO_INCREMENT, x int, PRIMARY KEY (id));");
|
||||
Test->tprintf("Doing INSERTs\n");
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0], (char*) "insert into t2 (x) values (1);");
|
||||
|
||||
Test->try_query(Test->galera->nodes[0], (char*) "insert into t2 (x) values (2);");
|
||||
Test->try_query(Test->galera->nodes[0], (char*) "insert into t2 (x) values (3);");
|
||||
|
||||
Test->try_query(Test->galera->nodes[1], (char*) "insert into t2 (x) values (4);");
|
||||
Test->try_query(Test->galera->nodes[1], (char*) "insert into t2 (x) values (5);");
|
||||
Test->try_query(Test->galera->nodes[1], (char*) "insert into t2 (x) values (6);");
|
||||
|
||||
Test->try_query(Test->galera->nodes[2], (char*) "insert into t2 (x) values (7);");
|
||||
Test->try_query(Test->galera->nodes[2], (char*) "insert into t2 (x) values (8);");
|
||||
Test->try_query(Test->galera->nodes[2], (char*) "insert into t2 (x) values (9);");
|
||||
Test->try_query(Test->galera->nodes[2], (char*) "insert into t2 (x) values (10);");
|
||||
|
||||
Test->stop_timeout();
|
||||
Test->repl->sync_slaves();
|
||||
|
||||
Test->tprintf("Trying \n");
|
||||
char last_insert_id1[1024];
|
||||
char last_insert_id2[1024];
|
||||
if ((
|
||||
find_field(Test->maxscales->conn_rwsplit[0],
|
||||
sel1,
|
||||
"last_insert_id()",
|
||||
&last_insert_id1[0])
|
||||
!= 0 ) || (
|
||||
find_field(Test->maxscales->conn_rwsplit[0],
|
||||
sel2,
|
||||
"last_insert_id()",
|
||||
&last_insert_id2[0])
|
||||
!= 0 ))
|
||||
{
|
||||
Test->tprintf("last_insert_id() fied not found!!\n");
|
||||
delete Test;
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Test->tprintf("'%s' gave last_insert_id() %s\n", sel1, last_insert_id1);
|
||||
Test->tprintf("'%s' gave last_insert_id() %s\n", sel2, last_insert_id2);
|
||||
Test->add_result(strcmp(last_insert_id1, last_insert_id2),
|
||||
"last_insert_id() are different depending in which order terms are in SELECT\n");
|
||||
}
|
||||
|
||||
char id_str[1024];
|
||||
char str1[1024];
|
||||
int iterations = 150;
|
||||
|
||||
for (int i = 100; i < iterations; i++)
|
||||
{
|
||||
Test->set_timeout(50);
|
||||
Test->add_result(execute_query(Test->maxscales->conn_rwsplit[0],
|
||||
"insert into t2 (x) values (%d);",
|
||||
i),
|
||||
"Query failed");
|
||||
|
||||
sprintf(str1, "select * from t2 where x=%d;", i);
|
||||
|
||||
find_field(Test->maxscales->conn_rwsplit[0], sel1, "last_insert_id()", &last_insert_id1[0]);
|
||||
find_field(Test->maxscales->conn_rwsplit[0], str1, "id", &id_str[0]);
|
||||
|
||||
int n = 0;
|
||||
|
||||
while (strcmp(last_insert_id1, id_str) != 0 && n < 5)
|
||||
{
|
||||
Test->tprintf("Replication is lagging");
|
||||
sleep(1);
|
||||
find_field(Test->maxscales->conn_rwsplit[0], str1, "id", &id_str[0]);
|
||||
n++;
|
||||
}
|
||||
|
||||
Test->add_result(strcmp(last_insert_id1, id_str),
|
||||
"last_insert_id is not equal to id even after waiting 5 seconds");
|
||||
|
||||
if (i % 10 == 0)
|
||||
{
|
||||
Test->tprintf("last_insert_id is %s, id is %s", last_insert_id1, id_str);
|
||||
}
|
||||
}
|
||||
|
||||
Test->check_maxscale_alive(0);
|
||||
|
||||
int rval = Test->global_result;
|
||||
delete Test;
|
||||
return rval;
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/**
|
||||
* @file bug634.cpp regression case for bug 634 ("SHOW SLAVE STATUS in RW SPLITTER is send to master")
|
||||
*
|
||||
* - execute SHOW SLAVE STATUS and check resut
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Description Stephane VAROQUI 2014-12-03 10:41:30 UTC
|
||||
* SHOW SLAVE STATUS in RW SPLITTER is send to master ? That could break some monitoring scripts for generic
|
||||
* proxy abstraction .
|
||||
* Comment 1 Vilho Raatikka 2014-12-03 11:10:12 UTC
|
||||
* COM_SHOW_SLAVE_STAT was unknown to query classifier. Being fixed.
|
||||
* Comment 2 Vilho Raatikka 2014-12-03 11:26:17 UTC
|
||||
* COM_SHOW_SLAVE_STAT wasn't classified but it was treated as 'unknown' and thus routed to master.
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include "testconnections.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConnections* Test = new TestConnections(argc, argv);
|
||||
Test->set_timeout(5);
|
||||
|
||||
char master_ip[100];
|
||||
|
||||
Test->maxscales->connect_maxscale(0);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
Test->set_timeout(5);
|
||||
Test->add_result(find_field(Test->maxscales->conn_rwsplit[0],
|
||||
(char*) "SHOW SLAVE STATUS",
|
||||
(char*) "Master_Host",
|
||||
master_ip),
|
||||
"Master_host files is not found in the SHOW SLAVE STATUS reply, probably query went to master\n");
|
||||
Test->add_result(strcmp(master_ip, Test->repl->IP_private[0]), "Master IP is wrong\n");
|
||||
}
|
||||
|
||||
Test->maxscales->close_maxscale_connections(0);
|
||||
int rval = Test->global_result;
|
||||
delete Test;
|
||||
return rval;
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
/**
|
||||
* @file bug694.cpp - regression test for bug694 ("RWSplit: SELECT @a:=@a+1 as a, test.b FROM test breaks
|
||||
* client session")
|
||||
*
|
||||
* - set use_sql_variables_in=all in MaxScale.cnf
|
||||
* - connect to readwritesplit router and execute:
|
||||
* @verbatim
|
||||
* CREATE TABLE test (b integer);
|
||||
* SELECT @a:=@a+1 as a, test.b FROM test;
|
||||
* USE test
|
||||
* @endverbatim
|
||||
* - check if MaxScale alive
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Description Vilho Raatikka 2015-01-14 08:09:45 UTC
|
||||
* Reproduce:
|
||||
* - set use_sql_variables_in=all in MaxScale.cnf
|
||||
* - connect to readwritesplit router and execute:
|
||||
* CREATE TABLE test (b integer);
|
||||
* SELECT @a:=@a+1 as a, test.b FROM test;
|
||||
* USE test
|
||||
*
|
||||
* You'll get:
|
||||
* ERROR 2006 (HY000): MySQL server has gone away
|
||||
*
|
||||
* It is a known limitation that SELÈCTs with SQL variable modifications are not supported. The issue is that
|
||||
* they aren't detected and as a consequence hte client session is disconnected.
|
||||
*
|
||||
* It is possible to detect this kind of query in query classifier, but set_query_type loses part of the
|
||||
* information. If both SELECT and SQL variable update are detected they can be stored in query type and
|
||||
* rwsplit could, for example, prevent from executing the query, execute it in master only (and log), force
|
||||
* all SQL variable modifications from that point to master (and log), etc.
|
||||
* Comment 1 Vilho Raatikka 2015-01-15 13:19:18 UTC
|
||||
* query_classifier.cc: set_query_type lost previous query type if the new was more restrictive. Problem was
|
||||
* that if query is both READ and SESSION_WRITE and configuration parameter use_sql_variables_in=all was set,
|
||||
* routing target became ambiguous. Replaced call to set_query_type with simply adding new type to type (=bit
|
||||
* field) and checking unsupported combinations in readwritesplit.c:get_route_target. If such a case is met, a
|
||||
* detailed error is written to error log in readwritesplit.c. mysql_client.c sees the error code and sends an
|
||||
* error to client. Then mysql_client.c calls router's handleError which ensures that there are enough backend
|
||||
* servers so that the session can continue.
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include "testconnections.h"
|
||||
#include "mariadb_func.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConnections* Test = new TestConnections(argc, argv);
|
||||
|
||||
Test->set_timeout(120);
|
||||
Test->maxscales->connect_maxscale(0);
|
||||
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0], "USE test");
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0], "DROP TABLE IF EXISTS test");
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0], "CREATE TABLE test (b integer)");
|
||||
|
||||
const int iter = Test->smoke ? 10 : 100;
|
||||
Test->tprintf("Creating and inserting %d rows into a table\n", iter);
|
||||
|
||||
for (int i = 0; i < iter; i++)
|
||||
{
|
||||
Test->set_timeout(30);
|
||||
execute_query(Test->maxscales->conn_rwsplit[0], "insert into test value(2);");
|
||||
Test->stop_timeout();
|
||||
}
|
||||
|
||||
Test->set_timeout(200);
|
||||
|
||||
Test->tprintf("Trying SELECT @a:=@a+1 as a, test.b FROM test\n");
|
||||
if (execute_query(Test->maxscales->conn_rwsplit[0], "SELECT @a:=@a+1 as a, test.b FROM test;") == 0)
|
||||
{
|
||||
Test->add_result(1, "Query succeded, but expected to fail.\n");
|
||||
}
|
||||
Test->tprintf("Trying USE test\n");
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0], "USE test");
|
||||
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0], "DROP TABLE IF EXISTS test");
|
||||
|
||||
Test->tprintf("Checking if MaxScale alive\n");
|
||||
Test->maxscales->close_maxscale_connections(0);
|
||||
|
||||
Test->tprintf("Checking logs\n");
|
||||
Test->check_log_err(0,
|
||||
(char*)
|
||||
"The query can't be routed to all backend servers because it includes SELECT and SQL variable modifications which is not supported",
|
||||
true);
|
||||
Test->check_log_err(0,
|
||||
(char*)
|
||||
"SELECT with session data modification is not supported if configuration parameter use_sql_variables_in=all",
|
||||
true);
|
||||
|
||||
Test->check_maxscale_alive(0);
|
||||
|
||||
int rval = Test->global_result;
|
||||
delete Test;
|
||||
return rval;
|
||||
}
|
@ -1,278 +0,0 @@
|
||||
/**
|
||||
* @file bug699.cpp regression case for bug 699 ( "rw-split sensitive to order of terms in field list of
|
||||
* SELECT (round 2)" )
|
||||
*
|
||||
* - compare @@hostname from "select @@wsrep_node_name, @@hostname" and "select @@hostname,
|
||||
*@@wsrep_node_name"
|
||||
* - comapre @@server_id from "select @@wsrep_node_name, @@server_id" and "select @@server_id,
|
||||
*@@wsrep_node_name"
|
||||
*/
|
||||
|
||||
/*
|
||||
* Kolbe Kegel 2015-01-16 18:38:15 UTC
|
||||
* I opened bug #509 some time ago, but that bug was handled specifically for the case of last_insert_id().
|
||||
* The crux of that bug still exists in 1.0.4 GA:
|
||||
*
|
||||
* [root@max1 ~]# mysql -h 127.0.0.1 -P 4006 -u maxuser -pmaxpwd -e 'select @@hostname, @@wsrep_node_name;
|
||||
* select @@wsrep_node_name, @@hostname;'
|
||||
+------------+-------------------+
|
||||
| @@hostname | @@wsrep_node_name |
|
||||
+------------+-------------------+
|
||||
| db2 | db2 |
|
||||
+------------+-------------------+
|
||||
+-------------------+------------+
|
||||
| @@wsrep_node_name | @@hostname |
|
||||
+-------------------+------------+
|
||||
| db3 | db3 |
|
||||
+-------------------+------------+
|
||||
|
|
||||
| In a single connection, fetching the values of the same two system variables results in the query being
|
||||
|routed differently depending on the order of the variables.
|
||||
|
|
||||
| Is there some set of variables that should always be routed to the master for some reason? If so, that
|
||||
|should be documented.
|
||||
|
|
||||
| Regardless, the order of terms in the SELECT list should not have any effect on query routing.
|
||||
| Comment 1 Vilho Raatikka 2015-01-16 22:33:38 UTC
|
||||
| @@wsrep_node_name can be resolved only in backend, MaxScale doesn't know about it. As a consequence, Since
|
||||
|MaxScale doesn't know what it is it takes the safe bet and routes it to master.
|
||||
| Comment 2 Kolbe Kegel 2015-01-16 22:35:13 UTC
|
||||
| What does "(In reply to comment #1)
|
||||
| > @@wsrep_node_name can be resolved only in backend, MaxScale doesn't know
|
||||
| > about it. As a consequence, Since MaxScale doesn't know what it is it takes
|
||||
| > the safe bet and routes it to master.
|
||||
|
|
||||
| What do you mean by "resolved only in backend" and "MaxScale doesn't know about it"?
|
||||
|
|
||||
| How is @@wsrep_node_name different in that respect from any other server variable that could be different
|
||||
|on any given backend?
|
||||
| Comment 3 Vilho Raatikka 2015-01-16 23:01:31 UTC
|
||||
| (In reply to comment #2)
|
||||
| > What does "(In reply to comment #1)
|
||||
| > > @@wsrep_node_name can be resolved only in backend, MaxScale doesn't know
|
||||
| > > about it. As a consequence, Since MaxScale doesn't know what it is it takes
|
||||
| > > the safe bet and routes it to master.
|
||||
| >
|
||||
| > What do you mean by "resolved only in backend" and "MaxScale doesn't know
|
||||
| > about it"?
|
||||
| >
|
||||
| > How is @@wsrep_node_name different in that respect from any other server
|
||||
| > variable that could be different on any given backend?
|
||||
|
|
||||
| MaxScale doesn't know that there is such system variable as @@wsrep_node_name. In my understanding the
|
||||
|reason is that the embedded MariaDB server doesn't have Galera's patch. Thus the variable is unknown.
|
||||
| Comment 4 Kolbe Kegel 2015-01-16 23:03:13 UTC
|
||||
| > >
|
||||
| > > How is @@wsrep_node_name different in that respect from any other server
|
||||
| > > variable that could be different on any given backend?
|
||||
| >
|
||||
| > MaxScale doesn't know that there is such system variable as
|
||||
| > @@wsrep_node_name. In my understanding the reason is that the embedded
|
||||
| > MariaDB server doesn't have Galera's patch. Thus the variable is unknown.
|
||||
|
|
||||
| Ahh, right. That sounds familiar. But it's still quite strange that the order of variables in the SELECT
|
||||
|statement is meaningful, isn't it?
|
||||
| Comment 5 Vilho Raatikka 2015-01-16 23:09:47 UTC
|
||||
| (In reply to comment #4)
|
||||
| > > >
|
||||
| > > > How is @@wsrep_node_name different in that respect from any other server
|
||||
| > > > variable that could be different on any given backend?
|
||||
| > >
|
||||
| > > MaxScale doesn't know that there is such system variable as
|
||||
| > > @@wsrep_node_name. In my understanding the reason is that the embedded
|
||||
| > > MariaDB server doesn't have Galera's patch. Thus the variable is unknown.
|
||||
| >
|
||||
| > Ahh, right. That sounds familiar. But it's still quite strange that the
|
||||
| > order of variables in the SELECT statement is meaningful, isn't it?
|
||||
|
|
||||
| The effectiveness of atrribute order in SELECT clause is a bug which is fixed in
|
||||
|http://bugs.skysql.com/show_bug.cgi?id=694 .
|
||||
|
|
||||
| MaxScale's inability to detect different system variables is slightly problematic as well but haven't
|
||||
|really concentrated on finding a decent solution to it yet. It might, however, be necessary.
|
||||
| Comment 6 Vilho Raatikka 2015-01-16 23:55:56 UTC
|
||||
| Attribute order effectiveness is fixed in http://bugs.skysql.com/show_bug.cgi?id=694
|
||||
|
|
||||
| Inability to detect Galera's system variables is hard to overcome since Galera patch doesn't work with
|
||||
|embedded library and embedded library doesn't know Galera's system variables.
|
||||
| Comment 7 Vilho Raatikka 2015-01-17 09:38:09 UTC
|
||||
| Appeared that MariaDB parsing end result depends on the order of [known,unknown] system variable pair in
|
||||
|the query.
|
||||
|
|
||||
| There was similar-looking bug in query_classifier before which hide this one. However, debugging and
|
||||
|examining the resulting thd and lex for the following queries shows that thd->free_list is non-empty if
|
||||
|@@hostname (known variable) is before @@wsrep_node_name. If @@wsrep_node_name is first on the attribute list
|
||||
|the resulting thd->free_list==NULL.
|
||||
| In the former case resulting query type is QUERY_TYPE_SYSVAR_READ (routed to slaves) and in the latter
|
||||
|case it is unknown (routed to master).
|
||||
|
|
||||
| 1. select @@wsrep_node_name, @@hostname;
|
||||
| 2. select @@hostname, @@wsrep_node_name;
|
||||
|
|
||||
| Both queries produce similar response but routing them to master only limits scalability.
|
||||
| Comment 8 Mark Riddoch 2015-01-28 08:39:25 UTC
|
||||
| Raised this with the server team as the issue is related to the behaviour of the parser in the embedded
|
||||
|server. System variables are resolved at parse time, unknown variables result in a parse error normally,
|
||||
|however this order dependency is slightly puzzling.
|
||||
| Comment 9 Mark Riddoch 2015-02-13 10:06:08 UTC
|
||||
| Hi Sergei,
|
||||
|
|
||||
| we have an interesting bug in MaxScale related to parsing. If we try to parse the query
|
||||
|
|
||||
| select @@wsrep_node_name;
|
||||
|
|
||||
| Using the embedded server we link with we do not get a parse tree. A select of other system variables
|
||||
|works. I guess the parser is resolving the name of the variable rather than leaving it to the execution
|
||||
|phase. Since we do not have Galera this variable is unknown. What is even more strange is that if we have a
|
||||
|query of the form
|
||||
|
|
||||
| select @@hostname, @@wsrep_node_name;
|
||||
|
|
||||
| We do get a parse tree, but reversing the order of the select we again fail to get a parse tree with the
|
||||
|query
|
||||
|
|
||||
| select @@wsrep_node_name, @@hostname;
|
||||
|
|
||||
| For our purposes we would ideally like to disable the resolving of the variable name at parse time, since
|
||||
|that would give us flexibility with regard to new variables being introduced in the servers. Do you know if
|
||||
|this is possible or if there is some easy fix we can do to the MariaDB parser that will help us here?
|
||||
|
|
||||
| For your reference the MaxScale bug report can be found here http://bugs.skysql.com/show_bug.cgi?id=699
|
||||
|
|
||||
|
|
||||
| Thanks
|
||||
| Mark
|
||||
| Comment 10 Mark Riddoch 2015-02-13 10:08:34 UTC
|
||||
| Hi, Mark!
|
||||
|
|
||||
| On Jan 28, Mark Riddoch wrote:
|
||||
| > Hi Sergei,
|
||||
| >
|
||||
| > we have an interesting bug in MaxScale related to parsing. If we try
|
||||
| > to parse the query
|
||||
| >
|
||||
| > select @@wsrep_node_name;
|
||||
| >
|
||||
| > Using the embedded server we link with we do not get a parse tree. A
|
||||
| > select of other system variables works. I guess the parser is
|
||||
| > resolving the name of the variable rather than leaving it to the
|
||||
| > execution phase. Since we do not have Galera this variable is unknown.
|
||||
|
|
||||
| Right... That would be *very* difficult to fix, it'd require a pretty
|
||||
| serious refactoring to get this out of the parser.
|
||||
|
|
||||
| > What is even more strange is that if we have a query of the form
|
||||
| >
|
||||
| > select @@hostname, @@wsrep_node_name;
|
||||
| >
|
||||
| > We do get a parse tree, but reversing the order of the select we again
|
||||
| > fail to get a parse tree with the query
|
||||
| >
|
||||
| > select @@wsrep_node_name, @@hostname;
|
||||
|
|
||||
| That depends on what you call a "parse tree". Items of the select clause
|
||||
| are stored in the thd->lex->current_select->item_list.
|
||||
|
|
||||
| For the first query, the list have 1 element, Item_func_get_system_var
|
||||
| for @@hostname.
|
||||
|
|
||||
| For the second query the list has 0 elements. In both cases, I've
|
||||
| examined the list in the debugger after MYSQLparse() returned.
|
||||
|
|
||||
| So apparently the parsing as aborted as soon as unknown variable is
|
||||
| encountered.
|
||||
|
|
||||
| > For our purposes we would ideally like to disable the resolving of the
|
||||
| > variable name at parse time, since that would give us flexibility with
|
||||
| > regard to new variables being introduced in the servers. Do you know
|
||||
| > if this is possible or if there is some easy fix we can do to the
|
||||
| > MariaDB parser that will help us here?
|
||||
|
|
||||
| I don't see how you can do that from MaxScale.
|
||||
| This looks like something that has to be fixed in the server.
|
||||
| Perhaps - not sure - it'd be possible to introduce some "mode" for the
|
||||
| parser where it doesn't check for valid variable names in certain
|
||||
| contextes.
|
||||
|
|
||||
| Regards,
|
||||
| Sergei
|
||||
|
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include "testconnections.h"
|
||||
|
||||
const char* sel1 = "select @@wsrep_node_name, @@hostname";
|
||||
const char* sel2 = "select @@hostname, @@wsrep_node_name";
|
||||
|
||||
const char* sel3 = "select @@wsrep_node_name, @@server_id";
|
||||
const char* sel4 = "select @@server_id, @@wsrep_node_name";
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConnections* Test = new TestConnections(argc, argv);
|
||||
Test->set_timeout(20);
|
||||
|
||||
Test->maxscales->connect_maxscale(0);
|
||||
|
||||
Test->tprintf("Trying \n");
|
||||
|
||||
char serverid1[1024];
|
||||
char serverid2[1024];
|
||||
|
||||
if ((
|
||||
find_field(Test->maxscales->conn_rwsplit[0],
|
||||
sel3,
|
||||
"@@server_id",
|
||||
&serverid1[0])
|
||||
!= 0 ) || (
|
||||
find_field(Test->maxscales->conn_rwsplit[0],
|
||||
sel4,
|
||||
"@@server_id",
|
||||
&serverid2[0])
|
||||
!= 0 ))
|
||||
{
|
||||
Test->add_result(1, "@@server_id field not found!!\n");
|
||||
delete Test;
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Test->tprintf("'%s' to RWSplit gave @@server_id %s\n", sel3, serverid1);
|
||||
Test->tprintf("'%s' directly to master gave @@server_id %s\n", sel4, serverid2);
|
||||
Test->add_result(strcmp(serverid1, serverid2),
|
||||
"server_id are different depending in which order terms are in SELECT\n");
|
||||
}
|
||||
|
||||
if ((
|
||||
find_field(Test->maxscales->conn_rwsplit[0],
|
||||
sel1,
|
||||
"@@hostname",
|
||||
&serverid1[0])
|
||||
!= 0 ) || (
|
||||
find_field(Test->maxscales->conn_rwsplit[0],
|
||||
sel2,
|
||||
"@@hostname",
|
||||
&serverid2[0])
|
||||
!= 0 ))
|
||||
{
|
||||
Test->add_result(1, "@@hostname field not found!!\n");
|
||||
delete Test;
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Test->tprintf("'%s' to RWSplit gave @@hostname %s\n", sel1, serverid1);
|
||||
Test->tprintf("'%s' to RWSplit gave @@hostname %s\n", sel2, serverid2);
|
||||
Test->add_result(strcmp(serverid1, serverid2),
|
||||
"hostname are different depending in which order terms are in SELECT\n");
|
||||
}
|
||||
|
||||
Test->maxscales->close_maxscale_connections(0);
|
||||
Test->check_maxscale_alive(0);
|
||||
int rval = Test->global_result;
|
||||
delete Test;
|
||||
return rval;
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
/**
|
||||
* @file bug711.cpp bug711 regression case (Some MySQL Workbench Management actions hang with R/W split
|
||||
* router)
|
||||
* - configure rwsplit with use_sql_variables_in=all
|
||||
* - try SHOW GLOBAL STATUS with all maxscales->routers[0]
|
||||
* - check if Maxscale is still alive
|
||||
*/
|
||||
|
||||
/*
|
||||
* Massimiliano 2015-01-29 15:35:52 UTC
|
||||
* Some MySQL Workbench Management actions hang with R/W split router
|
||||
*
|
||||
* MySQL Workbench 6.2 on OSX
|
||||
*
|
||||
*
|
||||
* When selecting "Users and Privileges" the client gets hanged.
|
||||
*
|
||||
*
|
||||
*
|
||||
* The quick solution is setting "use_sql_variables_in" in MaxScale config file for R/W split router section
|
||||
*
|
||||
* [RW_Split]
|
||||
* type=service
|
||||
* router=readwritesplit
|
||||
* servers=server3,server2
|
||||
* user=massi
|
||||
* passwd=xxxx
|
||||
*
|
||||
* use_sql_variables_in=master
|
||||
*
|
||||
*
|
||||
*
|
||||
* This way everything seems ok
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include "testconnections.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConnections* Test = new TestConnections(argc, argv);
|
||||
Test->maxscales->connect_maxscale(0);
|
||||
Test->set_timeout(10);
|
||||
Test->tprintf("Trying SHOW GLOBAL STATUS against RWSplit\n");
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0], (char*) "SHOW GLOBAL STATUS;");
|
||||
Test->tprintf("Trying SHOW GLOBAL STATUS against ReadConn master\n");
|
||||
Test->try_query(Test->maxscales->conn_master[0], (char*) "SHOW GLOBAL STATUS;");
|
||||
Test->tprintf("Trying SHOW GLOBAL STATUS against ReadConn slave\n");
|
||||
Test->try_query(Test->maxscales->conn_slave[0], (char*) "SHOW GLOBAL STATUS;");
|
||||
Test->check_maxscale_alive(0);
|
||||
int rval = Test->global_result;
|
||||
delete Test;
|
||||
return rval;
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
[maxscale]
|
||||
threads=###threads###
|
||||
log_warning=1
|
||||
|
||||
[MySQL Monitor]
|
||||
type=monitor
|
||||
module=mysqlmon
|
||||
servers= server1, server2,server3 ,server4
|
||||
user=maxskysql
|
||||
password= skysql
|
||||
|
||||
[RW Split Router]
|
||||
type=service
|
||||
router= readwritesplit
|
||||
servers=server1, server2, server3,server4
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
use_sql_variables_in=all
|
||||
|
||||
[Read Connection Router Slave]
|
||||
type=service
|
||||
router=readconnroute
|
||||
router_options= slave
|
||||
servers=server1,server2,server3,server4
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
|
||||
[Read Connection Router Master]
|
||||
type=service
|
||||
router=readconnroute
|
||||
router_options=master
|
||||
servers=server1,server2,server3,server4
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
|
||||
[RW Split Listener]
|
||||
type=listener
|
||||
service=RW Split Router
|
||||
protocol=MySQLClient
|
||||
port=4006
|
||||
#socket=/tmp/rwsplit.sock
|
||||
|
||||
[Read Connection Listener Slave]
|
||||
type=listener
|
||||
service=Read Connection Router Slave
|
||||
protocol=MySQLClient
|
||||
port=4009
|
||||
|
||||
[Read Connection Listener Master]
|
||||
type=listener
|
||||
service=Read Connection Router Master
|
||||
protocol=MySQLClient
|
||||
port=4008
|
||||
|
||||
|
||||
[CLI]
|
||||
type=service
|
||||
router=cli
|
||||
|
||||
[CLI Listener]
|
||||
type=listener
|
||||
service=CLI
|
||||
protocol=maxscaled
|
||||
#address=localhost
|
||||
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
|
||||
|
||||
[server4]
|
||||
type=server
|
||||
address=###node_server_IP_4###
|
||||
port=###node_server_port_4###
|
||||
protocol=MySQLBackend
|
||||
|
@ -1,90 +0,0 @@
|
||||
[maxscale]
|
||||
threads=###threads###
|
||||
log_warning=1
|
||||
|
||||
[MySQL Monitor]
|
||||
type=monitor
|
||||
module=mysqlmon
|
||||
servers= server1, server2,server3 ,server4
|
||||
user=maxskysql
|
||||
password= skysql
|
||||
|
||||
[RW Split Router]
|
||||
type=service
|
||||
router= readwritesplit
|
||||
servers=server1, server2, server3,server4
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
slave_selection_criteria=LEAST_ROUTER_CONNECTIONS
|
||||
use_sql_variables_in=all
|
||||
|
||||
[Read Connection Router Slave]
|
||||
type=service
|
||||
router=readconnroute
|
||||
router_options= slave
|
||||
servers=server1,server2,server3,server4
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
|
||||
[Read Connection Router Master]
|
||||
type=service
|
||||
router=readconnroute
|
||||
router_options=master
|
||||
servers=server1,server2,server3,server4
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
|
||||
[RW Split Listener]
|
||||
type=listener
|
||||
service=RW Split Router
|
||||
protocol=MySQLClient
|
||||
port=4006
|
||||
#socket=/tmp/rwsplit.sock
|
||||
|
||||
[Read Connection Listener Slave]
|
||||
type=listener
|
||||
service=Read Connection Router Slave
|
||||
protocol=MySQLClient
|
||||
port=4009
|
||||
|
||||
[Read Connection Listener Master]
|
||||
type=listener
|
||||
service=Read Connection Router Master
|
||||
protocol=MySQLClient
|
||||
port=4008
|
||||
|
||||
[CLI]
|
||||
type=service
|
||||
router=cli
|
||||
|
||||
[CLI Listener]
|
||||
type=listener
|
||||
service=CLI
|
||||
protocol=maxscaled
|
||||
#address=localhost
|
||||
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
|
||||
|
||||
[server4]
|
||||
type=server
|
||||
address=###node_server_IP_4###
|
||||
port=###node_server_port_4###
|
||||
protocol=MySQLBackend
|
||||
|
@ -1,90 +0,0 @@
|
||||
[maxscale]
|
||||
threads=###threads###
|
||||
log_warning=1
|
||||
|
||||
[MySQL Monitor]
|
||||
type=monitor
|
||||
module=mysqlmon
|
||||
servers= server1, server2,server3 ,server4
|
||||
user=maxskysql
|
||||
password= skysql
|
||||
|
||||
[RW Split Router]
|
||||
type=service
|
||||
router= readwritesplit
|
||||
servers=server1, server2, server3,server4
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
slave_selection_criteria=LEAST_ROUTER_CONNECTIONS
|
||||
disable_sescmd_history=true
|
||||
|
||||
[Read Connection Router Slave]
|
||||
type=service
|
||||
router=readconnroute
|
||||
router_options= slave
|
||||
servers=server1,server2,server3,server4
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
|
||||
[Read Connection Router Master]
|
||||
type=service
|
||||
router=readconnroute
|
||||
router_options=master
|
||||
servers=server1,server2,server3,server4
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
|
||||
[RW Split Listener]
|
||||
type=listener
|
||||
service=RW Split Router
|
||||
protocol=MySQLClient
|
||||
port=4006
|
||||
#socket=/tmp/rwsplit.sock
|
||||
|
||||
[Read Connection Listener Slave]
|
||||
type=listener
|
||||
service=Read Connection Router Slave
|
||||
protocol=MySQLClient
|
||||
port=4009
|
||||
|
||||
[Read Connection Listener Master]
|
||||
type=listener
|
||||
service=Read Connection Router Master
|
||||
protocol=MySQLClient
|
||||
port=4008
|
||||
|
||||
[CLI]
|
||||
type=service
|
||||
router=cli
|
||||
|
||||
[CLI Listener]
|
||||
type=listener
|
||||
service=CLI
|
||||
protocol=maxscaled
|
||||
#address=localhost
|
||||
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
|
||||
|
||||
[server4]
|
||||
type=server
|
||||
address=###node_server_IP_4###
|
||||
port=###node_server_port_4###
|
||||
protocol=MySQLBackend
|
||||
|
@ -1,69 +0,0 @@
|
||||
[maxscale]
|
||||
threads=###threads###
|
||||
log_info=1
|
||||
|
||||
[MySQL Monitor]
|
||||
type=monitor
|
||||
module=mysqlmon
|
||||
servers=server1,server2,server3,server4
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
monitor_interval=1000
|
||||
detect_standalone_master=true
|
||||
failcount=2
|
||||
allow_cluster_recovery=true
|
||||
|
||||
[RW Split Router]
|
||||
type=service
|
||||
router=readwritesplit
|
||||
servers=server1,server2,server3,server4
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
master_failure_mode=fail_on_write
|
||||
|
||||
[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
|
||||
|
||||
[CLI Network Listener]
|
||||
type=listener
|
||||
service=CLI
|
||||
protocol=maxscaled
|
||||
address=127.0.0.1
|
||||
port=6603
|
||||
|
||||
[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
|
||||
|
||||
[server4]
|
||||
type=server
|
||||
address=###node_server_IP_4###
|
||||
port=###node_server_port_4###
|
||||
protocol=MySQLBackend
|
@ -1,56 +0,0 @@
|
||||
[maxscale]
|
||||
threads=4
|
||||
|
||||
[MySQL Monitor]
|
||||
type=monitor
|
||||
module=mysqlmon
|
||||
servers=server1,server2
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
monitor_interval=1000
|
||||
detect_standalone_master=true
|
||||
failcount=2
|
||||
allow_cluster_recovery=true
|
||||
|
||||
[Traffic Router]
|
||||
type=service
|
||||
router=readconnroute
|
||||
router_options=master
|
||||
servers=server1,server2
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
|
||||
[Traffic Listener]
|
||||
type=listener
|
||||
service=Traffic Router
|
||||
protocol=MySQLClient
|
||||
port=4006
|
||||
|
||||
[CLI]
|
||||
type=service
|
||||
router=cli
|
||||
|
||||
[CLI Listener]
|
||||
type=listener
|
||||
service=CLI
|
||||
protocol=maxscaled
|
||||
socket=default
|
||||
|
||||
[CLI Network Listener]
|
||||
type=listener
|
||||
service=CLI
|
||||
protocol=maxscaled
|
||||
address=127.0.0.1
|
||||
port=6603
|
||||
|
||||
[server1]
|
||||
type=server
|
||||
address=node-000
|
||||
port=3306
|
||||
protocol=MySQLBackend
|
||||
|
||||
[server2]
|
||||
type=server
|
||||
address=node-001
|
||||
port=3306
|
||||
protocol=MySQLBackend
|
@ -1,61 +0,0 @@
|
||||
[maxscale]
|
||||
threads=4
|
||||
|
||||
[MySQL-Monitor]
|
||||
type=monitor
|
||||
module=mysqlmon
|
||||
servers=server1,server2,server3
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
monitor_interval=1000
|
||||
detect_standalone_master=true
|
||||
failcount=2
|
||||
allow_cluster_recovery=true
|
||||
|
||||
[Traffic-Router]
|
||||
type=service
|
||||
router=readconnroute
|
||||
router_options=master
|
||||
servers=server1,server2,server3
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
|
||||
[Traffic-Listener]
|
||||
type=listener
|
||||
service=Traffic-Router
|
||||
protocol=MySQLClient
|
||||
port=4006
|
||||
|
||||
[CLI]
|
||||
type=service
|
||||
router=cli
|
||||
|
||||
[CLI-Listener]
|
||||
type=listener
|
||||
service=CLI
|
||||
protocol=maxscaled
|
||||
socket=default
|
||||
|
||||
[CLI-Network-Listener]
|
||||
type=listener
|
||||
service=CLI
|
||||
protocol=maxscaled
|
||||
port=6603
|
||||
|
||||
[server1]
|
||||
type=server
|
||||
address=node-000
|
||||
port=3306
|
||||
protocol=MySQLBackend
|
||||
|
||||
[server2]
|
||||
type=server
|
||||
address=node-001
|
||||
port=3306
|
||||
protocol=MySQLBackend
|
||||
|
||||
[server3]
|
||||
type=server
|
||||
address=node-002
|
||||
port=3306
|
||||
protocol=MySQLBackend
|
@ -1,86 +0,0 @@
|
||||
[maxscale]
|
||||
threads=###threads###
|
||||
|
||||
[MySQL Monitor]
|
||||
type=monitor
|
||||
module=mysqlmon
|
||||
servers=server1,server2,server3,server4
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
monitor_interval=1000
|
||||
|
||||
[RW Split Router]
|
||||
type=service
|
||||
router=readwritesplit
|
||||
servers=server1,server2
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
|
||||
[Read Connection Router Slave]
|
||||
type=service
|
||||
router=readconnroute
|
||||
router_options=slave
|
||||
servers=server1,server2,server3,server4
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
|
||||
[Read Connection Router Master]
|
||||
type=service
|
||||
router=readconnroute
|
||||
router_options=master
|
||||
servers=server1,server2,server3,server4
|
||||
user=maxskysql
|
||||
password=skysql
|
||||
|
||||
[RW Split Listener]
|
||||
type=listener
|
||||
service=RW Split Router
|
||||
protocol=MySQLClient
|
||||
port=4006
|
||||
|
||||
[Read Connection Listener Slave]
|
||||
type=listener
|
||||
service=Read Connection Router Slave
|
||||
protocol=MySQLClient
|
||||
port=4009
|
||||
|
||||
[Read Connection Listener Master]
|
||||
type=listener
|
||||
service=Read Connection Router Master
|
||||
protocol=MySQLClient
|
||||
port=4008
|
||||
|
||||
[CLI]
|
||||
type=service
|
||||
router=cli
|
||||
|
||||
[CLI Listener]
|
||||
type=listener
|
||||
service=CLI
|
||||
protocol=maxscaled
|
||||
#address=localhost
|
||||
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
|
||||
|
||||
[server4]
|
||||
type=server
|
||||
address=###node_server_IP_4###
|
||||
port=###node_server_port_4###
|
||||
protocol=MySQLBackend
|
@ -1,51 +0,0 @@
|
||||
/**
|
||||
* @file mxs127.cpp - bug mxs-127 regression case ("disable_sescmd_history causes MaxScale to crash under
|
||||
* load")
|
||||
* - execute set @test=%d 10000 times against RWSplit, ReadConn Master and ReadConn Slave
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include "testconnections.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConnections* Test = new TestConnections(argc, argv);
|
||||
Test->set_timeout(10);
|
||||
int i;
|
||||
char sql[256];
|
||||
|
||||
Test->maxscales->connect_maxscale(0);
|
||||
|
||||
Test->tprintf("RWSplit: Executing set @test=i 10000 times\n");
|
||||
for (i = 0; i < 10000; i++)
|
||||
{
|
||||
Test->set_timeout(5);
|
||||
sprintf(sql, "set @test=%d", i);
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0], "%s", sql);
|
||||
}
|
||||
Test->tprintf("done!\n");
|
||||
|
||||
printf("ReadConn Master: Executing set @test=i 10000 times\n");
|
||||
for (i = 0; i < 10000; i++)
|
||||
{
|
||||
Test->set_timeout(5);
|
||||
sprintf(sql, "set @test=%d", i);
|
||||
Test->try_query(Test->maxscales->conn_master[0], "%s", sql);
|
||||
}
|
||||
Test->tprintf("done!\n");
|
||||
|
||||
Test->tprintf("ReadConn Slave: Executing set @test=i 10000 times\n");
|
||||
for (i = 0; i < 10000; i++)
|
||||
{
|
||||
Test->set_timeout(5);
|
||||
sprintf(sql, "set @test=%d", i);
|
||||
Test->try_query(Test->maxscales->conn_slave[0], "%s", sql);
|
||||
}
|
||||
Test->tprintf("done!\n");
|
||||
|
||||
Test->maxscales->close_maxscale_connections(0);
|
||||
int rval = Test->global_result;
|
||||
delete Test;
|
||||
return rval;
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
/**
|
||||
* MXS-1786: Hang with COM_STATISTICS
|
||||
*/
|
||||
|
||||
#include "testconnections.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConnections test(argc, argv);
|
||||
|
||||
test.maxscales->connect();
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
test.set_timeout(10);
|
||||
mysql_stat(test.maxscales->conn_rwsplit[0]);
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "SELECT 1");
|
||||
}
|
||||
|
||||
test.maxscales->disconnect();
|
||||
|
||||
|
||||
return test.global_result;
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/**
|
||||
* @file mxs47.cpp Regression test for bug MXS-47 ("Session freeze when small tail packet")
|
||||
* - execute SELECT REPEAT('a',i), where 'i' is changing from 1 to 3000 with stride of 7 using readwritesplit
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include "testconnections.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConnections test(argc, argv);
|
||||
int iterations = 5000;
|
||||
|
||||
test.tprintf("Executing `SELECT REPEAT('a', X );` for X = 0..%d with a stride of 7", iterations);
|
||||
test.maxscales->connect_maxscale(0);
|
||||
|
||||
for (int i = 1; i < iterations; i += 7)
|
||||
{
|
||||
char str[1024];
|
||||
sprintf(str, "SELECT REPEAT('a',%d)", i);
|
||||
|
||||
test.set_timeout(15);
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "%s", str);
|
||||
}
|
||||
|
||||
test.maxscales->close_maxscale_connections(0);
|
||||
|
||||
return test.global_result;
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
/**
|
||||
* @file mxs682_cyrillic.cpp put cyrillic letters to the table
|
||||
* - put string with Cyrillic into table
|
||||
* - check SELECT from backend
|
||||
*/
|
||||
|
||||
#include "testconnections.h"
|
||||
|
||||
void check_val(MYSQL* conn, TestConnections& test)
|
||||
{
|
||||
char val[256] = "<failed to read value>";
|
||||
test.set_timeout(30);
|
||||
find_field(conn, "SELECT * FROM t2", "x", val);
|
||||
test.tprintf("result: %s\n", val);
|
||||
test.add_result(strcmp("Кот", val) != 0, "Wrong SELECT result: %s\n", val);
|
||||
test.stop_timeout();
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConnections test(argc, argv);
|
||||
Mariadb_nodes* nodes = strstr(test.test_name, "galera") ? test.galera : test.repl;
|
||||
|
||||
test.set_timeout(60);
|
||||
|
||||
test.maxscales->connect();
|
||||
|
||||
auto conn = test.maxscales->conn_rwsplit[0];
|
||||
execute_query_silent(conn, "DROP TABLE t2;");
|
||||
test.try_query(conn, "CREATE TABLE t2 (x varchar(10));");
|
||||
test.try_query(conn, "INSERT INTO t2 VALUES (\"Кот\");");
|
||||
|
||||
test.maxscales->disconnect();
|
||||
|
||||
test.stop_timeout();
|
||||
test.repl->connect();
|
||||
test.repl->sync_slaves();
|
||||
test.repl->disconnect();
|
||||
|
||||
test.set_timeout(60);
|
||||
test.maxscales->connect();
|
||||
check_val(test.maxscales->conn_rwsplit[0], test);
|
||||
check_val(test.maxscales->conn_master[0], test);
|
||||
check_val(test.maxscales->conn_slave[0], test);
|
||||
test.maxscales->disconnect();
|
||||
|
||||
nodes->connect();
|
||||
for (int i = 0; i < test.repl->N; i++)
|
||||
{
|
||||
check_val(nodes->nodes[i], test);
|
||||
}
|
||||
nodes->disconnect();
|
||||
|
||||
return test.global_result;
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/**
|
||||
* @file mxs957.cpp Execute given SQL through readwritesplit (with temporary tables usage)
|
||||
*
|
||||
*
|
||||
* Execute the following SQL through readwritesplit without errors.
|
||||
*
|
||||
* CREATE OR REPLACE TABLE t1(`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
|
||||
* CREATE OR REPLACE TABLE t2(`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
|
||||
* CREATE TEMPORARY TABLE temp1(`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
|
||||
* INSERT INTO temp1 values (1), (2), (3);
|
||||
* INSERT INTO t1 values (1), (2), (3);
|
||||
* INSERT INTO t2 values (1), (2), (3);
|
||||
* CREATE TEMPORARY TABLE temp2
|
||||
* SELECT DISTINCT p.id FROM temp1 p JOIN t1 t ON (t.id = p.id)
|
||||
* LEFT JOIN t2 ON (t.id = t2.id)
|
||||
* WHERE p.id IS NOT NULL AND @@server_id IS NOT NULL;
|
||||
* SELECT * FROM temp2;
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include "testconnections.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
const char* queries[] =
|
||||
{
|
||||
"USE test",
|
||||
"CREATE OR REPLACE TABLE t1(`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY)",
|
||||
"CREATE OR REPLACE TABLE t2(`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY)",
|
||||
"CREATE TEMPORARY TABLE temp1(`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY)",
|
||||
"INSERT INTO temp1 values (1), (2), (3)",
|
||||
"INSERT INTO t1 values (1), (2), (3)",
|
||||
"INSERT INTO t2 values (1), (2), (3)",
|
||||
"CREATE TEMPORARY TABLE temp2 SELECT DISTINCT p.id FROM temp1 p JOIN t1 t ON (t.id = p.id) LEFT JOIN t2 ON (t.id = t2.id) WHERE p.id IS NOT NULL AND @@server_id IS NOT NULL",
|
||||
"SELECT * FROM temp2",
|
||||
"DROP TABLE t1",
|
||||
"DROP TABLE t2",
|
||||
NULL
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConnections* Test = new TestConnections(argc, argv);
|
||||
Test->maxscales->connect_maxscale(0);
|
||||
|
||||
for (int i = 0; queries[i]; i++)
|
||||
{
|
||||
Test->set_timeout(30);
|
||||
Test->try_query(Test->maxscales->conn_rwsplit[0], "%s", queries[i]);
|
||||
}
|
||||
int rval = Test->global_result;
|
||||
delete Test;
|
||||
return rval;
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
/**
|
||||
* Test replication-manager
|
||||
*/
|
||||
|
||||
#include "testconnections.h"
|
||||
#include <termios.h>
|
||||
|
||||
void prepare()
|
||||
{
|
||||
struct termios t;
|
||||
tcgetattr(STDIN_FILENO, &t);
|
||||
t.c_iflag |= IGNBRK;
|
||||
t.c_iflag &= ~ECHO;
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &t);
|
||||
}
|
||||
|
||||
void get_output(TestConnections& test)
|
||||
{
|
||||
test.tprintf("Maxadmin output:");
|
||||
char* output = test.maxscales->ssh_node_f(0, true, "maxadmin list servers");
|
||||
test.tprintf("%s", output);
|
||||
free(output);
|
||||
|
||||
test.tprintf("replication-manager output:");
|
||||
output = test.maxscales->ssh_node_f(0,
|
||||
true,
|
||||
"cat /var/log/replication-manager.log && sudo truncate -s 0 /var/log/replication-manager.log");
|
||||
test.tprintf("%s", output);
|
||||
free(output);
|
||||
}
|
||||
|
||||
static int inserts = 0;
|
||||
|
||||
void check(TestConnections& test)
|
||||
{
|
||||
MYSQL* conn = test.maxscales->open_rwsplit_connection(0);
|
||||
const char* query1 = "INSERT INTO test.t1 VALUES (%d)";
|
||||
const char* query2 = "SELECT * FROM test.t1";
|
||||
|
||||
test.try_query(conn, "BEGIN");
|
||||
test.tprintf(query1, inserts);
|
||||
test.try_query(conn, query1, inserts++);
|
||||
mysql_query(conn, query2);
|
||||
|
||||
MYSQL_RES* res = mysql_store_result(conn);
|
||||
test.add_result(res == NULL, "Query shoud return a result set");
|
||||
|
||||
if (res)
|
||||
{
|
||||
std::string values;
|
||||
MYSQL_ROW row;
|
||||
int num_rows = mysql_num_rows(res);
|
||||
test.add_result(num_rows != inserts,
|
||||
"Query returned %d rows when %d rows were expected",
|
||||
num_rows,
|
||||
inserts);
|
||||
const char* separator = "";
|
||||
|
||||
while ((row = mysql_fetch_row(res)))
|
||||
{
|
||||
values += separator;
|
||||
values += row[0];
|
||||
separator = ", ";
|
||||
}
|
||||
|
||||
test.tprintf("%s: %s", query2, values.c_str());
|
||||
}
|
||||
|
||||
test.try_query(conn, "COMMIT");
|
||||
mysql_close(conn);
|
||||
}
|
||||
|
||||
static bool interactive = false;
|
||||
|
||||
void get_input()
|
||||
{
|
||||
if (interactive)
|
||||
{
|
||||
printf("--- Press any key to confinue ---\n");
|
||||
getchar();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
interactive = strcmp(argv[argc - 1], "interactive") == 0;
|
||||
prepare();
|
||||
|
||||
TestConnections test(argc, argv);
|
||||
test.tprintf("Installing replication-manager");
|
||||
int rc = system("./manage_mrm.sh install > manage_mrm.log");
|
||||
if (!WIFEXITED(rc) || WEXITSTATUS(rc) != 0)
|
||||
{
|
||||
test.tprintf("Failed to install replication-manager, see manage_mrm.log for more details");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Wait a few seconds
|
||||
sleep(5);
|
||||
|
||||
test.tprintf("Creating table and inserting data");
|
||||
get_input();
|
||||
test.maxscales->connect_maxscale(0);
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "CREATE OR REPLACE TABLE test.t1(id INT)");
|
||||
|
||||
check(test);
|
||||
get_output(test);
|
||||
|
||||
test.tprintf("Stopping master and waiting for it to fail over");
|
||||
get_input();
|
||||
test.repl->stop_node(0);
|
||||
sleep(10);
|
||||
|
||||
check(test);
|
||||
get_output(test);
|
||||
|
||||
test.tprintf("Stopping another node and waiting for replication-manager to detect it");
|
||||
get_input();
|
||||
test.repl->stop_node(1);
|
||||
sleep(10);
|
||||
|
||||
check(test);
|
||||
get_output(test);
|
||||
get_input();
|
||||
|
||||
test.tprintf("Stopping all but one node and waiting for replication-manager to detect it");
|
||||
get_input();
|
||||
test.repl->stop_node(2);
|
||||
sleep(10);
|
||||
|
||||
check(test);
|
||||
get_output(test);
|
||||
|
||||
test.tprintf("Starting all nodes and wait for replication-manager to fix the replication");
|
||||
get_input();
|
||||
|
||||
test.repl->start_node(0, (char*)"");
|
||||
sleep(5);
|
||||
test.repl->start_node(1, (char*)"");
|
||||
sleep(5);
|
||||
test.repl->start_node(2, (char*)"");
|
||||
sleep(5);
|
||||
|
||||
check(test);
|
||||
get_output(test);
|
||||
|
||||
test.tprintf("Dropping tables");
|
||||
get_input();
|
||||
test.maxscales->close_maxscale_connections(0);
|
||||
test.maxscales->connect_maxscale(0);
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "DROP TABLE test.t1");
|
||||
test.maxscales->close_maxscale_connections(0);
|
||||
|
||||
get_output(test);
|
||||
|
||||
test.tprintf("Removing replication-manager");
|
||||
get_input();
|
||||
system("./manage_mrm.sh remove >> manage_mrm.log");
|
||||
test.repl->fix_replication();
|
||||
return test.global_result;
|
||||
}
|
@ -1,211 +0,0 @@
|
||||
/**
|
||||
* Test replication-manager - Two node setup
|
||||
*/
|
||||
|
||||
#include "testconnections.h"
|
||||
#include <termios.h>
|
||||
|
||||
void prepare(TestConnections& test)
|
||||
{
|
||||
struct termios t;
|
||||
tcgetattr(STDIN_FILENO, &t);
|
||||
t.c_iflag |= IGNBRK;
|
||||
t.c_iflag &= ~ECHO;
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &t);
|
||||
|
||||
test.maxscales->ssh_node_f(0,
|
||||
true,
|
||||
"pcs resource disable maxscale-clone; pcs resource disable replication-manager");
|
||||
|
||||
test.repl->fix_replication();
|
||||
system("./manage_mrm.sh configure 2");
|
||||
test.maxscales->copy_from_node((char*)"/etc/maxscale.cnf", (char*)".", 0);
|
||||
test.maxscales->copy_to_node("./config.toml", "~", 0);
|
||||
test.maxscales->ssh_node_f(0,
|
||||
false,
|
||||
"sudo cp ~/maxscale.cnf /etc/; sudo cp ~/config.toml /etc/replication-manager/");
|
||||
|
||||
system("sed -i 's/version_string=.*/version_string=10.1.19-maxscale-standby/' ./maxscale.cnf");
|
||||
test.galera->copy_to_node("./maxscale.cnf", "~", 0);
|
||||
test.galera->copy_to_node("./config.toml", "~", 0);
|
||||
test.galera->ssh_node(0, "sudo cp ~/config.toml /etc/replication-manager", false);
|
||||
test.galera->ssh_node(0, "sudo cp ~/maxscale.cnf /etc/", false);
|
||||
test.maxscales->ssh_node_f(0,
|
||||
true,
|
||||
"replication-manager bootstrap --clean-all;pcs resource enable maxscale-clone; pcs resource enable replication-manager");
|
||||
sleep(5);
|
||||
}
|
||||
|
||||
void get_output(TestConnections& test)
|
||||
{
|
||||
test.tprintf("Maxadmin output:");
|
||||
char* output = test.maxscales->ssh_node_f(0, true, "maxadmin list servers");
|
||||
test.tprintf("%s", output);
|
||||
free(output);
|
||||
}
|
||||
|
||||
static int inserts = 0;
|
||||
|
||||
void check(TestConnections& test)
|
||||
{
|
||||
MYSQL* conn = test.maxscales->open_rwsplit_connection(0);
|
||||
const char* query1 = "INSERT INTO test.t1 VALUES (%d)";
|
||||
const char* query2 = "SELECT * FROM test.t1";
|
||||
|
||||
printf("\nExecuting queries though MaxScale:\n\n");
|
||||
printf("BEGIN\n");
|
||||
test.try_query(conn, "BEGIN");
|
||||
printf(query1, inserts);
|
||||
printf("\n");
|
||||
test.try_query(conn, query1, inserts++);
|
||||
mysql_query(conn, query2);
|
||||
|
||||
MYSQL_RES* res = mysql_store_result(conn);
|
||||
test.add_result(res == NULL, "Query shoud return a result set");
|
||||
|
||||
if (res)
|
||||
{
|
||||
std::string values;
|
||||
MYSQL_ROW row;
|
||||
int num_rows = mysql_num_rows(res);
|
||||
test.add_result(num_rows != inserts,
|
||||
"Query returned %d rows when %d rows were expected",
|
||||
num_rows,
|
||||
inserts);
|
||||
const char* separator = "";
|
||||
|
||||
while ((row = mysql_fetch_row(res)))
|
||||
{
|
||||
values += separator;
|
||||
values += row[0];
|
||||
separator = ", ";
|
||||
}
|
||||
|
||||
printf("%s\n%s\n", query2, values.c_str());
|
||||
mysql_free_result(res);
|
||||
}
|
||||
|
||||
mysql_query(conn, "SELECT @@server_id, @@hostname");
|
||||
res = mysql_store_result(conn);
|
||||
if (res)
|
||||
{
|
||||
MYSQL_ROW row;
|
||||
while ((row = mysql_fetch_row(res)))
|
||||
{
|
||||
printf("SELECT @@server_id, @@hostname\n%s, %s\n", row[0], row[1]);
|
||||
}
|
||||
mysql_free_result(res);
|
||||
}
|
||||
|
||||
printf("COMMIT\n");
|
||||
test.try_query(conn, "COMMIT");
|
||||
|
||||
mysql_query(conn, "SELECT @@server_id, @@hostname");
|
||||
res = mysql_store_result(conn);
|
||||
if (res)
|
||||
{
|
||||
MYSQL_ROW row;
|
||||
while ((row = mysql_fetch_row(res)))
|
||||
{
|
||||
printf("SELECT @@server_id, @@hostname\n%s, %s\n", row[0], row[1]);
|
||||
}
|
||||
mysql_free_result(res);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
get_output(test);
|
||||
|
||||
mysql_close(conn);
|
||||
}
|
||||
|
||||
static bool interactive = false;
|
||||
|
||||
void get_input()
|
||||
{
|
||||
if (interactive)
|
||||
{
|
||||
printf("--- Press any key to confinue ---\n");
|
||||
getchar();
|
||||
}
|
||||
}
|
||||
|
||||
void do_sleep(int s)
|
||||
{
|
||||
printf("Waiting for %d seconds.", s);
|
||||
fflush(stdout);
|
||||
|
||||
for (int i = 0; i < s; i++)
|
||||
{
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
printf(" Done!\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
interactive = strcmp(argv[argc - 1], "interactive") == 0;
|
||||
TestConnections::check_nodes(false);
|
||||
TestConnections::skip_maxscale_start(true);
|
||||
TestConnections test(argc, argv);
|
||||
prepare(test);
|
||||
|
||||
test.tprintf("Creating table and inserting data");
|
||||
get_input();
|
||||
test.maxscales->connect_maxscale(0);
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "CREATE OR REPLACE TABLE test.t1(id INT)");
|
||||
test.maxscales->close_maxscale_connections(0);
|
||||
|
||||
check(test);
|
||||
|
||||
test.tprintf("Stopping the slave");
|
||||
get_input();
|
||||
test.repl->stop_node(1);
|
||||
do_sleep(15);
|
||||
|
||||
check(test);
|
||||
|
||||
test.tprintf("Restarting the slave");
|
||||
get_input();
|
||||
test.repl->start_node(1, (char*)"");
|
||||
do_sleep(15);
|
||||
|
||||
check(test);
|
||||
|
||||
test.tprintf("Stopping master and waiting for it to fail over");
|
||||
get_input();
|
||||
test.repl->stop_node(0);
|
||||
do_sleep(15);
|
||||
|
||||
check(test);
|
||||
|
||||
test.tprintf("Restarting old master");
|
||||
get_input();
|
||||
test.repl->start_node(0, (char*)"");
|
||||
do_sleep(15);
|
||||
|
||||
check(test);
|
||||
|
||||
test.tprintf("Stopping the promoted master and waiting for replication-manager to detect it");
|
||||
get_input();
|
||||
test.repl->stop_node(1);
|
||||
do_sleep(15);
|
||||
|
||||
check(test);
|
||||
|
||||
test.tprintf("Restarting the promoted master");
|
||||
get_input();
|
||||
test.repl->start_node(1, (char*)"");
|
||||
do_sleep(15);
|
||||
|
||||
check(test);
|
||||
|
||||
test.maxscales->connect_maxscale(0);
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "DROP TABLE test.t1");
|
||||
test.maxscales->close_maxscale_connections(0);
|
||||
|
||||
return test.global_result;
|
||||
}
|
@ -1,233 +0,0 @@
|
||||
/**
|
||||
* Test replication-manager - Three node setup
|
||||
*/
|
||||
|
||||
#include "testconnections.h"
|
||||
#include <termios.h>
|
||||
|
||||
void prepare(TestConnections& test)
|
||||
{
|
||||
struct termios t;
|
||||
tcgetattr(STDIN_FILENO, &t);
|
||||
t.c_iflag |= IGNBRK;
|
||||
t.c_iflag &= ~ECHO;
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &t);
|
||||
|
||||
test.maxscales->ssh_node_f(0,
|
||||
true,
|
||||
"pcs resource disable maxscale-clone; pcs resource disable replication-manager");
|
||||
|
||||
test.repl->fix_replication();
|
||||
system("./manage_mrm.sh configure 3");
|
||||
test.maxscales->copy_from_node((char*)"/etc/maxscale.cnf", (char*)".", 0);
|
||||
test.maxscales->copy_to_node("./config.toml", "~", 0);
|
||||
test.maxscales->ssh_node_f(0,
|
||||
false,
|
||||
"sudo cp ~/maxscale.cnf /etc/; sudo cp ~/config.toml /etc/replication-manager/");
|
||||
|
||||
system("sed -i 's/version_string=.*/version_string=10.1.19-maxscale-standby/' ./maxscale.cnf");
|
||||
test.galera->copy_to_node("./maxscale.cnf", "~", 0);
|
||||
test.galera->copy_to_node("./config.toml", "~", 0);
|
||||
test.galera->ssh_node(0, "sudo cp ~/config.toml /etc/replication-manager", false);
|
||||
test.galera->ssh_node(0, "sudo cp ~/maxscale.cnf /etc/", false);
|
||||
test.maxscales->ssh_node_f(0,
|
||||
true,
|
||||
"replication-manager bootstrap --clean-all;pcs resource enable maxscale-clone; pcs resource enable replication-manager");
|
||||
sleep(5);
|
||||
}
|
||||
|
||||
void get_output(TestConnections& test)
|
||||
{
|
||||
test.tprintf("Maxadmin output:");
|
||||
char* output = test.maxscales->ssh_node_f(0, true, "maxadmin list servers");
|
||||
test.tprintf("%s", output);
|
||||
free(output);
|
||||
}
|
||||
|
||||
static int inserts = 0;
|
||||
|
||||
void check(TestConnections& test)
|
||||
{
|
||||
MYSQL* conn = test.maxscales->open_rwsplit_connection(0);
|
||||
const char* query1 = "INSERT INTO test.t1 VALUES (%d)";
|
||||
const char* query2 = "SELECT * FROM test.t1";
|
||||
|
||||
printf("\nExecuting queries though MaxScale:\n\n");
|
||||
printf("BEGIN\n");
|
||||
test.try_query(conn, "BEGIN");
|
||||
printf(query1, inserts);
|
||||
printf("\n");
|
||||
test.try_query(conn, query1, inserts++);
|
||||
mysql_query(conn, query2);
|
||||
|
||||
MYSQL_RES* res = mysql_store_result(conn);
|
||||
test.add_result(res == NULL, "Query shoud return a result set");
|
||||
|
||||
if (res)
|
||||
{
|
||||
std::string values;
|
||||
MYSQL_ROW row;
|
||||
int num_rows = mysql_num_rows(res);
|
||||
test.add_result(num_rows != inserts,
|
||||
"Query returned %d rows when %d rows were expected",
|
||||
num_rows,
|
||||
inserts);
|
||||
const char* separator = "";
|
||||
|
||||
while ((row = mysql_fetch_row(res)))
|
||||
{
|
||||
values += separator;
|
||||
values += row[0];
|
||||
separator = ", ";
|
||||
}
|
||||
|
||||
printf("%s\n%s\n", query2, values.c_str());
|
||||
mysql_free_result(res);
|
||||
}
|
||||
|
||||
mysql_query(conn, "SELECT @@server_id, @@hostname");
|
||||
res = mysql_store_result(conn);
|
||||
if (res)
|
||||
{
|
||||
MYSQL_ROW row;
|
||||
while ((row = mysql_fetch_row(res)))
|
||||
{
|
||||
printf("SELECT @@server_id, @@hostname\n%s, %s\n", row[0], row[1]);
|
||||
}
|
||||
mysql_free_result(res);
|
||||
}
|
||||
|
||||
printf("COMMIT\n");
|
||||
test.try_query(conn, "COMMIT");
|
||||
|
||||
mysql_query(conn, "SELECT @@server_id, @@hostname");
|
||||
res = mysql_store_result(conn);
|
||||
if (res)
|
||||
{
|
||||
MYSQL_ROW row;
|
||||
while ((row = mysql_fetch_row(res)))
|
||||
{
|
||||
printf("SELECT @@server_id, @@hostname\n%s, %s\n", row[0], row[1]);
|
||||
}
|
||||
mysql_free_result(res);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
get_output(test);
|
||||
|
||||
mysql_close(conn);
|
||||
}
|
||||
|
||||
static bool interactive = false;
|
||||
|
||||
void get_input()
|
||||
{
|
||||
if (interactive)
|
||||
{
|
||||
printf("--- Press any key to confinue ---\n");
|
||||
getchar();
|
||||
}
|
||||
}
|
||||
|
||||
void do_sleep(int s)
|
||||
{
|
||||
printf("Waiting for %d seconds.", s);
|
||||
fflush(stdout);
|
||||
|
||||
for (int i = 0; i < s; i++)
|
||||
{
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
printf(" Done!\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
interactive = strcmp(argv[argc - 1], "interactive") == 0;
|
||||
TestConnections::check_nodes(false);
|
||||
TestConnections::skip_maxscale_start(true);
|
||||
TestConnections test(argc, argv);
|
||||
prepare(test);
|
||||
|
||||
test.tprintf("Creating table and inserting data");
|
||||
get_input();
|
||||
test.maxscales->connect_maxscale(0);
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "CREATE OR REPLACE TABLE test.t1(id INT)");
|
||||
test.maxscales->close_maxscale_connections(0);
|
||||
|
||||
check(test);
|
||||
|
||||
// test.tprintf("Stopping master and waiting for it to fail over");
|
||||
// get_input();
|
||||
// test.repl->stop_node(0);
|
||||
// do_sleep(15);
|
||||
|
||||
// check(test);
|
||||
|
||||
// test.tprintf("Restarting old master");
|
||||
// get_input();
|
||||
// test.repl->start_node(0, (char*)"");
|
||||
// do_sleep(15);
|
||||
|
||||
// check(test);
|
||||
|
||||
test.tprintf("Stopping the first slave");
|
||||
get_input();
|
||||
test.repl->stop_node(1);
|
||||
do_sleep(15);
|
||||
|
||||
check(test);
|
||||
|
||||
|
||||
test.tprintf("Stopping the second slave");
|
||||
get_input();
|
||||
test.repl->stop_node(2);
|
||||
do_sleep(15);
|
||||
|
||||
check(test);
|
||||
|
||||
test.tprintf("Restarting the second slave");
|
||||
get_input();
|
||||
test.repl->start_node(2, (char*)"");
|
||||
do_sleep(15);
|
||||
|
||||
check(test);
|
||||
|
||||
test.tprintf("Stopping the master and waiting for it to fail over");
|
||||
get_input();
|
||||
test.repl->stop_node(0);
|
||||
do_sleep(15);
|
||||
|
||||
check(test);
|
||||
|
||||
// test.tprintf("Stopping first slave, the second slave is promoted as the master");
|
||||
// get_input();
|
||||
// test.repl->stop_node(1);
|
||||
// do_sleep(15);
|
||||
|
||||
// check(test);
|
||||
|
||||
// test.tprintf("Restarting the first slave");
|
||||
// get_input();
|
||||
test.repl->start_node(1, (char*)"");
|
||||
// do_sleep(15);
|
||||
|
||||
// check(test);
|
||||
|
||||
// test.tprintf("Restarting the original master");
|
||||
// get_input();
|
||||
test.repl->start_node(0, (char*)"");
|
||||
do_sleep(5);
|
||||
|
||||
// check(test);
|
||||
|
||||
test.maxscales->connect_maxscale(0);
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "DROP TABLE test.t1");
|
||||
test.maxscales->close_maxscale_connections(0);
|
||||
|
||||
return test.global_result;
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/**
|
||||
* Readwritesplit read-only transaction test
|
||||
*
|
||||
* - Check that read-only transactions are routed to slaves
|
||||
*/
|
||||
|
||||
#include "testconnections.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
TestConnections test(argc, argv);
|
||||
|
||||
char master_id[200];
|
||||
char slave_id[200];
|
||||
|
||||
// Get the server IDs of the master and the slave
|
||||
test.repl->connect();
|
||||
sprintf(master_id, "%d", test.repl->get_server_id(0));
|
||||
sprintf(slave_id, "%d", test.repl->get_server_id(1));
|
||||
|
||||
test.maxscales->connect_maxscale(0);
|
||||
|
||||
execute_query_silent(test.maxscales->conn_rwsplit[0], "DROP TABLE test.t1");
|
||||
execute_query_silent(test.maxscales->conn_rwsplit[0], "CREATE TABLE test.t1(id int)");
|
||||
|
||||
// Test read-only transaction with commit
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "START TRANSACTION READ ONLY");
|
||||
test.add_result(execute_query_check_one(test.maxscales->conn_rwsplit[0], "SELECT @@server_id", slave_id),
|
||||
"Query should be routed to slave");
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "COMMIT");
|
||||
|
||||
// Test read-only transaction with rollback
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "START TRANSACTION READ ONLY");
|
||||
test.add_result(execute_query_check_one(test.maxscales->conn_rwsplit[0], "SELECT @@server_id", slave_id),
|
||||
"Query should be routed to slave");
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "ROLLBACK");
|
||||
|
||||
// Test normal transaction
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "START TRANSACTION");
|
||||
test.add_result(execute_query_check_one(test.maxscales->conn_rwsplit[0], "SELECT @@server_id", master_id),
|
||||
"Query should be routed to master");
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "COMMIT");
|
||||
|
||||
// Test writes in read-only transaction
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "START TRANSACTION READ ONLY");
|
||||
test.add_result(execute_query_check_one(test.maxscales->conn_rwsplit[0], "SELECT @@server_id", slave_id),
|
||||
"Query should be routed to slave");
|
||||
test.add_result(execute_query(test.maxscales->conn_rwsplit[0], "UPDATE test.t1 SET id=0") == 0,
|
||||
"Query should fail");
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "COMMIT");
|
||||
|
||||
|
||||
test.maxscales->close_maxscale_connections(0);
|
||||
|
||||
return test.global_result;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user