Merge branch '2.2' into develop
This commit is contained in:
commit
b96228f95c
@ -712,9 +712,6 @@ add_test_executable(mxs1808_long_data.cpp mxs1808_long_data replication LABELS r
|
||||
# https://jira.mariadb.org/browse/MXS-1824
|
||||
add_test_executable(mxs1824_double_cursor.cpp mxs1824_double_cursor replication LABELS readwritesplit REPL_BACKEND)
|
||||
|
||||
# TODO: Remove this once the problem with the connector is resolved
|
||||
set_tests_properties(mxs1824_double_cursor PROPERTIES WILL_FAIL TRUE)
|
||||
|
||||
# MXS-1828: Multiple LOAD DATA LOCAL INFILE commands in one query cause a hang
|
||||
# https://jira.mariadb.org/browse/MXS-1828
|
||||
add_test_executable(mxs1828_double_local_infile.cpp mxs1828_double_local_infile replication LABELS readwritesplit REPL_BACKEND)
|
||||
@ -1009,6 +1006,10 @@ add_test_executable(mxs1889.cpp mxs1889 mxs1889 LABELS REPL_BACKEND)
|
||||
# MXS-421 Improved log facility
|
||||
add_test_executable(mxs421_events.cpp mxs421_events mxs421_events LABELS REPL_BACKEND)
|
||||
|
||||
# MXS-1926: LOAD DATA LOCAL INFILE interrupted by server shutdown
|
||||
# https://jira.mariadb.org/browse/MXS-1926
|
||||
add_test_executable(mxs1926_killed_server.cpp mxs1926_killed_server mxs1926_killed_server LABELS readwritesplit REPL_BACKEND)
|
||||
|
||||
# MXS-1932: Hidden files are not ignored
|
||||
# https://jira.mariadb.org/browse/MXS-1932
|
||||
add_test_executable(mxs1932_hidden_cnf.cpp mxs1932_hidden_cnf replication LABELS REPL_BACKEND)
|
||||
|
57
maxscale-system-test/cnf/maxscale.cnf.template.mxs1926_killed_server
Executable file
57
maxscale-system-test/cnf/maxscale.cnf.template.mxs1926_killed_server
Executable file
@ -0,0 +1,57 @@
|
||||
[maxscale]
|
||||
threads=###threads###
|
||||
|
||||
[MySQL Monitor]
|
||||
type=monitor
|
||||
module=mysqlmon
|
||||
servers=server1,server2,server3,server4
|
||||
user=maxskysql
|
||||
passwd=skysql
|
||||
monitor_interval=1000
|
||||
|
||||
[RW Split Router]
|
||||
type=service
|
||||
router=readwritesplit
|
||||
servers=server1,server2,server3,server4
|
||||
user=maxskysql
|
||||
passwd=skysql
|
||||
|
||||
[RW Split Listener]
|
||||
type=listener
|
||||
service=RW Split Router
|
||||
protocol=MySQLClient
|
||||
port=4006
|
||||
|
||||
[CLI]
|
||||
type=service
|
||||
router=cli
|
||||
|
||||
[CLI Listener]
|
||||
type=listener
|
||||
service=CLI
|
||||
protocol=maxscaled
|
||||
socket=default
|
||||
|
||||
[server1]
|
||||
type=server
|
||||
address=###node_server_IP_1###
|
||||
port=###node_server_port_1###
|
||||
protocol=MySQLBackend
|
||||
|
||||
[server2]
|
||||
type=server
|
||||
address=###node_server_IP_2###
|
||||
port=###node_server_port_2###
|
||||
protocol=MySQLBackend
|
||||
|
||||
[server3]
|
||||
type=server
|
||||
address=###node_server_IP_3###
|
||||
port=###node_server_port_3###
|
||||
protocol=MySQLBackend
|
||||
|
||||
[server4]
|
||||
type=server
|
||||
address=###node_server_IP_4###
|
||||
port=###node_server_port_4###
|
||||
protocol=MySQLBackend
|
@ -75,6 +75,7 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
if (test.maxscales->start() == 0)
|
||||
{
|
||||
sleep(10);
|
||||
test.maxscales->wait_for_monitor();
|
||||
|
||||
if (test.maxscales->connect_rwsplit() == 0)
|
||||
|
106
maxscale-system-test/mxs1926_killed_server.cpp
Normal file
106
maxscale-system-test/mxs1926_killed_server.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
/**
|
||||
* MXS-1926: LOAD DATA LOCAL INFILE interrupted by server shutdown
|
||||
*
|
||||
* https://jira.mariadb.org/browse/MXS-1926
|
||||
*/
|
||||
|
||||
#include "testconnections.h"
|
||||
#include <stdlib.h>
|
||||
#include <thread>
|
||||
#include <fstream>
|
||||
#include <chrono>
|
||||
#include <atomic>
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
typedef high_resolution_clock Clock;
|
||||
|
||||
std::atomic<int> ROWCOUNT{10000};
|
||||
|
||||
std::string create_tmpfile()
|
||||
{
|
||||
char filename[] = "/tmp/data.csv.XXXXXX";
|
||||
int fd = mkstemp(filename);
|
||||
std::ofstream file(filename);
|
||||
close(fd);
|
||||
|
||||
for (int i = 0; i < ROWCOUNT; i++)
|
||||
{
|
||||
file << "1, 2, 3, 4\n";
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
void tune_rowcount(TestConnections& test)
|
||||
{
|
||||
milliseconds dur{1};
|
||||
test.tprintf("Tuning data size so that an insert takes 10 seconds");
|
||||
test.maxscales->connect();
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "SET sql_log_bin=0");
|
||||
|
||||
while (dur < seconds(10))
|
||||
{
|
||||
std::string filename = create_tmpfile();
|
||||
|
||||
auto start = Clock::now();
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "LOAD DATA LOCAL INFILE '%s' INTO TABLE test.t1",
|
||||
filename.c_str());
|
||||
auto end = Clock::now();
|
||||
dur = duration_cast<milliseconds>(end - start);
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "TRUNCATE TABLE test.t1", filename.c_str());
|
||||
|
||||
remove(filename.c_str());
|
||||
|
||||
int orig = ROWCOUNT;
|
||||
ROWCOUNT = orig / dur.count() * 10000;
|
||||
test.tprintf("Loading %d rows took %d ms, setting row count to %d",
|
||||
orig, dur.count(), ROWCOUNT.load());
|
||||
}
|
||||
|
||||
test.maxscales->disconnect();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
TestConnections test(argc, argv);
|
||||
|
||||
test.repl->connect();
|
||||
|
||||
// Create the table
|
||||
execute_query(test.repl->nodes[0], "CREATE OR REPLACE TABLE test.t1 (a INT, b INT, c INT, d INT)");
|
||||
test.repl->sync_slaves();
|
||||
|
||||
// Tune the amount of data so that the loading will take approximately 15 seconds
|
||||
tune_rowcount(test);
|
||||
|
||||
std::string filename = create_tmpfile();
|
||||
|
||||
// Connect to MaxScale and load enough data so that we have
|
||||
test.maxscales->connect();
|
||||
|
||||
// Disable replication of the LOAD DATA LOCAL INFILE
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "SET sql_log_bin=0");
|
||||
|
||||
test.tprintf("Loading %d rows of data while stopping a slave", ROWCOUNT.load());
|
||||
std::thread thr([&]()
|
||||
{
|
||||
std::this_thread::sleep_for(milliseconds(10));
|
||||
test.repl->stop_node(3);
|
||||
test.repl->start_node(3);
|
||||
});
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "LOAD DATA LOCAL INFILE '%s' INTO TABLE test.t1",
|
||||
filename.c_str());
|
||||
test.tprintf("Load complete");
|
||||
thr.join();
|
||||
|
||||
test.maxscales->disconnect();
|
||||
|
||||
// Cleanup
|
||||
execute_query(test.repl->nodes[0], "DROP TABLE test.t1");
|
||||
test.repl->sync_slaves();
|
||||
test.repl->disconnect();
|
||||
|
||||
remove(filename.c_str());
|
||||
return test.global_result;
|
||||
}
|
@ -16,6 +16,7 @@ int main(int argc, char** argv)
|
||||
TestConnections::skip_maxscale_start(true);
|
||||
TestConnections test(argc, argv);
|
||||
|
||||
// Create a file with a guaranteed bad configuration (turbochargers are not yet supported)
|
||||
ofstream cnf("hidden.cnf");
|
||||
cnf << "[something]" << endl;
|
||||
cnf << "type=turbocharger" << endl;
|
||||
@ -23,14 +24,18 @@ int main(int argc, char** argv)
|
||||
cnf << "speed=maximum" << endl;
|
||||
cnf.close();
|
||||
|
||||
// Copy the configuration to MaxScale
|
||||
test.maxscales->copy_to_node_legacy("hidden.cnf", "~");
|
||||
|
||||
// Move it into the maxscale.cnf.d directory and make it a hidden file
|
||||
test.maxscales->ssh_node_f(0, true,
|
||||
"mkdir -p /etc/maxscale.cnf.d/;"
|
||||
"mv %s/hidden.cnf /etc/maxscale.cnf.d/.hidden.cnf;"
|
||||
"chown -R maxscale:maxscale /etc/maxscale.cnf.d/",
|
||||
test.maxscales->access_homedir[0]);
|
||||
|
||||
test.assert(test.maxscales->restart_maxscale() == 0, "Starting MaxScale should suceed");
|
||||
// Make sure the hidden configuration is not read and that MaxScale starts up
|
||||
test.assert(test.maxscales->restart_maxscale() == 0, "Starting MaxScale should succeed");
|
||||
|
||||
test.maxscales->ssh_node_f(0, true, "rm -r /etc/maxscale.cnf.d/");
|
||||
remove("hidden.cnf");
|
||||
|
@ -87,19 +87,19 @@ bool Backend::execute_session_command()
|
||||
|
||||
CHK_DCB(m_dcb);
|
||||
|
||||
SessionCommandList::iterator iter = m_session_commands.begin();
|
||||
SessionCommand& sescmd = *(*iter);
|
||||
GWBUF *buffer = sescmd.deep_copy_buffer();
|
||||
SSessionCommand& sescmd = m_session_commands.front();
|
||||
GWBUF *buffer = sescmd->deep_copy_buffer();
|
||||
bool rval = false;
|
||||
|
||||
switch (sescmd.get_command())
|
||||
switch (sescmd->get_command())
|
||||
{
|
||||
case MXS_COM_QUIT:
|
||||
case MXS_COM_STMT_CLOSE:
|
||||
case MXS_COM_STMT_SEND_LONG_DATA:
|
||||
/** These commands do not generate responses */
|
||||
rval = write(buffer, NO_RESPONSE);
|
||||
rval = Backend::write(buffer, NO_RESPONSE);
|
||||
complete_session_command();
|
||||
ss_dassert(!is_waiting_result());
|
||||
break;
|
||||
|
||||
case MXS_COM_CHANGE_USER:
|
||||
@ -110,12 +110,11 @@ bool Backend::execute_session_command()
|
||||
|
||||
case MXS_COM_QUERY:
|
||||
default:
|
||||
/**
|
||||
* Mark session command buffer, it triggers writing
|
||||
* MySQL command to protocol
|
||||
*/
|
||||
// TODO: Remove use of GWBUF_TYPE_SESCMD
|
||||
//Mark session command buffer, it triggers writing MySQL command to protocol
|
||||
gwbuf_set_type(buffer, GWBUF_TYPE_SESCMD);
|
||||
rval = write(buffer);
|
||||
rval = Backend::write(buffer);
|
||||
ss_dassert(is_waiting_result());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ bool RWBackend::write(GWBUF* buffer, response_type type)
|
||||
}
|
||||
}
|
||||
|
||||
return mxs::Backend::write(buffer);
|
||||
return mxs::Backend::write(buffer, type);
|
||||
}
|
||||
|
||||
void RWBackend::close(close_type type)
|
||||
|
Loading…
x
Reference in New Issue
Block a user