Merge branch '2.3' into develop

This commit is contained in:
Markus Mäkelä
2019-06-03 13:46:13 +03:00
24 changed files with 357 additions and 57 deletions

View File

@ -199,6 +199,9 @@ add_test_executable(maxctrl_basic.cpp maxctrl_basic maxctrl_basic LABELS maxctrl
# MXS-2167: Monitors should be able to use extra_port
add_test_executable(mxs2167_extra_port.cpp mxs2167_extra_port mxs2167_extra_port LABELS REPL_BACKEND)
# Test KILL QUERY functionality
add_test_executable(kill_query.cpp kill_query replication LABELS REPL_BACKEND)
############################################
# BEGIN: Tests that require GTID #
############################################
@ -964,6 +967,12 @@ add_test_executable(pam_authentication.cpp pam_authentication pam_authentication
# MXS-2350: On-demand connection creation
add_test_executable(mxs2350_lazy_connect.cpp mxs2350_lazy_connect mxs2350_lazy_connect LABELS REPL_BACKEND)
# MXS-2520: Allow master reconnection on reads
add_test_executable(mxs2520_master_read_reconnect.cpp mxs2520_master_read_reconnect mxs2520_master_read_reconnect LABELS REPL_BACKEND readwritesplit)
# MXS-2464: Crash in route_stored_query with ReadWriteSplit
add_test_executable(mxs2464_sescmd_reconnect.cpp mxs2464_sescmd_reconnect mxs2464_sescmd_reconnect LABELS REPL_BACKEND readwritesplit)
############################################
# BEGIN: binlogrouter and avrorouter tests #
############################################

View File

@ -0,0 +1,29 @@
[maxscale]
threads=###threads###
[MySQL-Monitor]
type=monitor
module=mysqlmon
servers=###server_line###
user=maxskysql
password=skysql
monitor_interval=1000
backend_read_timeout=1
backend_connect_timeout=1
[RW-Split-Router]
type=service
router=readwritesplit
servers=###server_line###
user=maxskysql
password=skysql
delayed_retry_timeout=1
transaction_replay=true
[RW-Split-Listener]
type=listener
service=RW-Split-Router
protocol=MySQLClient
port=4006
###server###

View File

@ -0,0 +1,30 @@
[maxscale]
threads=###threads###
log_info=1
[MySQL-Monitor]
type=monitor
module=mysqlmon
servers=server1
user=maxskysql
password=skysql
monitor_interval=1000
backend_read_timeout=1
backend_connect_timeout=1
[RW-Split-Router]
type=service
router=readwritesplit
servers=server1
user=maxskysql
password=skysql
delayed_retry_timeout=45
transaction_replay=true
[RW-Split-Listener]
type=listener
service=RW-Split-Router
protocol=MySQLClient
port=4006
###server###

View File

@ -0,0 +1,50 @@
/**
* Test KILL QUERY functionality
*/
#include "testconnections.h"
int main(int argc, char* argv[])
{
TestConnections test(argc, argv);
auto conn = test.maxscales->rwsplit();
conn.connect();
conn.query("CREATE OR REPLACE TABLE test.t1 (id LONGTEXT)");
for (int x = 0; x < 10; x++)
{
conn.query("INSERT INTO test.t1 VALUES (REPEAT('a', 5000000))");
}
for (int i = 0; i < 3; i++)
{
auto a = test.maxscales->rwsplit();
auto b = test.maxscales->rwsplit();
test.expect(a.connect() && b.connect(), "Connections should work");
auto id = a.thread_id();
test.set_timeout(15);
std::thread thr(
[&]() {
// The ALTER should take longer than 15 seconds to complete so that a KILL is required to
// interrupt it.
test.expect(!a.query("ALTER TABLE test.t1 FORCE"), "ALTER should fail");
const char* expected = "Query execution was interrupted";
test.expect(strstr(a.error(), expected),
"Alter should fail with '%s' but it failed with '%s'",
expected, a.error());
});
test.expect(b.query("KILL QUERY " + std::to_string(id)), "KILL QUERY failed: %s", b.error());
thr.join();
test.stop_timeout();
}
conn.query("DROP TABLE test.t1");
return test.global_result;
}

View File

@ -348,6 +348,11 @@ public:
m_pw = pw;
}
uint32_t thread_id() const
{
return mysql_thread_id(m_conn);
}
private:
std::string m_host;
int m_port;

View File

@ -0,0 +1,35 @@
/**
* MXS-2464: Crash in route_stored_query with ReadWriteSplit
* https://jira.mariadb.org/browse/MXS-2464
*/
#include "testconnections.h"
int main(int argc, char* argv[])
{
TestConnections test(argc, argv);
test.maxscales->connect();
std::thread thr([&]() {
sleep(5);
test.tprintf("block node 0");
test.repl->block_node(0);
test.tprintf("wait for monitor");
test.maxscales->wait_for_monitor(2);
test.tprintf("unblock node 0");
test.repl->unblock_node(0);
});
constexpr const char* query = "SET @a = (SELECT SLEEP(10))";
test.set_timeout(60);
test.tprintf("%s", query);
test.try_query(test.maxscales->conn_rwsplit[0], query);
test.stop_timeout();
test.tprintf("disconnect");
test.maxscales->disconnect();
test.tprintf("join");
thr.join();
return test.global_result;
}

View File

@ -0,0 +1,34 @@
/**
* MXS-2520: Allow master reconnection on reads
* https://jira.mariadb.org/browse/MXS-2520
*/
#include "testconnections.h"
int main(int argc, char* argv[])
{
TestConnections test(argc, argv);
test.maxscales->connect();
std::thread thr([&]() {
sleep(5);
test.tprintf("block node 0");
test.repl->block_node(0);
test.tprintf("wait for monitor");
test.maxscales->wait_for_monitor(2);
test.tprintf("unblock node 0");
test.repl->unblock_node(0);
});
test.set_timeout(60);
test.tprintf("SELECT SLEEP(10)");
test.try_query(test.maxscales->conn_rwsplit[0], "SELECT SLEEP(10)");
test.stop_timeout();
test.tprintf("disconnect");
test.maxscales->disconnect();
test.tprintf("join");
thr.join();
return test.global_result;
}

View File

@ -322,11 +322,11 @@ int Nodes::read_basic_env()
{
// reading IPs
sprintf(env_name, "%s_%03d_network", prefix, i);
IP[i] = get_nc_item((char*) env_name);
IP[i] = strdup(get_nc_item(env_name).c_str());
// reading private IPs
sprintf(env_name, "%s_%03d_private_ip", prefix, i);
IP_private[i] = get_nc_item((char*) env_name);
IP_private[i] = strdup(get_nc_item(env_name).c_str());
if (IP_private[i] == NULL)
{
IP_private[i] = IP[i];
@ -335,7 +335,7 @@ int Nodes::read_basic_env()
// reading IPv6
sprintf(env_name, "%s_%03d_network6", prefix, i);
IP6[i] = get_nc_item((char*) env_name);
IP6[i] = strdup(get_nc_item(env_name).c_str());
if (IP6[i] == NULL)
{
IP6[i] = IP[i];
@ -344,11 +344,11 @@ int Nodes::read_basic_env()
//reading sshkey
sprintf(env_name, "%s_%03d_keyfile", prefix, i);
sshkey[i] = get_nc_item((char*) env_name);
sshkey[i] = strdup(get_nc_item(env_name).c_str());
sprintf(env_name, "%s_%03d_whoami", prefix, i);
access_user[i] = get_nc_item((char*) env_name);
access_user[i] = strdup(get_nc_item(env_name).c_str());
if (access_user[i] == NULL)
{
access_user[i] = (char *) "vagrant";
@ -369,7 +369,7 @@ int Nodes::read_basic_env()
}
sprintf(env_name, "%s_%03d_hostname", prefix, i);
hostname[i] = get_nc_item((char*) env_name);
hostname[i] = strdup(get_nc_item(env_name).c_str());
if (hostname[i] == NULL)
{
hostname[i] = IP[i];
@ -396,13 +396,14 @@ const char* Nodes::ip(int i) const
return use_ipv6 ? IP6[i] : IP[i];
}
char * Nodes::get_nc_item(char * item_name)
std::string Nodes::get_nc_item(const char* item_name)
{
size_t start = network_config.find(item_name);
if (start == std::string::npos)
{
return NULL;
return "";
}
size_t end = network_config.find("\n", start);
size_t equal = network_config.find("=", start);
if (end == std::string::npos)
@ -411,14 +412,14 @@ char * Nodes::get_nc_item(char * item_name)
}
if (equal == std::string::npos)
{
return NULL;
return "";
}
char * cstr = new char [end - equal + 1];
strcpy(cstr, network_config.substr(equal + 1, end - equal - 1).c_str());
setenv(item_name, cstr, 1);
std::string str = network_config.substr(equal + 1, end - equal - 1);
return (cstr);
setenv(item_name, str.c_str(), 1);
return str;
}
int Nodes::get_N()

View File

@ -181,9 +181,9 @@ public:
/**
* @brief get_nc_item Find variable in the MDBCI network_config file
* @param item_name Name of the variable
* @return value of variable
* @return value of variable or empty value if not found
*/
char *get_nc_item(char * item_name);
std::string get_nc_item(const char* item_name);
/**
* @brief get_N Calculate the number of nodes discribed in the _netoek_config file