Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
MXS-1323: Fix crash on attempted retry of read
When a backend is waiting for a response but no statement is stored for the session, the buffer where the stored statement is copied is not modified. This means that it needs to be initialized to a NULL value. Added a test that checks that the behavior works as expected even with persistent connections. A second test reproduces the crash by executing parallel SET commands while slaves are blocked. There is still a behavioral problem in readwritesplit. If a session command is being executed and it fails on a slave, an error is sent to the client. In this case it would not be necessary to close the session if the master is still alive.
- Loading branch information
Showing
7 changed files
with
206 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| [maxscale] | ||
| threads=###threads### | ||
| log_info=1 | ||
|
|
||
| [MySQL Monitor] | ||
| type=monitor | ||
| module=mysqlmon | ||
| ###repl51### | ||
| servers= server1,server2 | ||
| user=maxskysql | ||
| passwd= skysql | ||
| monitor_interval=500 | ||
|
|
||
| [RW Split Router] | ||
| type=service | ||
| router= readwritesplit | ||
| servers=server1,server2 | ||
| 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 | ||
| persistpoolmax=10 | ||
| persistmaxtime=300 | ||
|
|
||
| [server2] | ||
| type=server | ||
| address=###node_server_IP_2### | ||
| port=###node_server_port_2### | ||
| protocol=MySQLBackend | ||
| persistpoolmax=10 | ||
| persistmaxtime=300 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| /** | ||
| * Test for MXS-1323. | ||
| * - Check that retried reads work with persistent connections | ||
| */ | ||
|
|
||
| #include "testconnections.h" | ||
|
|
||
| void* async_block(void* data) | ||
| { | ||
| TestConnections *test = (TestConnections*)data; | ||
| sleep(5); | ||
| test->tprintf("Blocking slave"); | ||
| test->repl->block_node(1); | ||
| return NULL; | ||
| } | ||
|
|
||
| std::string do_query(TestConnections& test) | ||
| { | ||
| MYSQL* conn = test.open_rwsplit_connection(); | ||
|
|
||
| const char* query = "SELECT SLEEP(10), @@server_id"; | ||
| char output[512] = ""; | ||
|
|
||
| find_field(conn, query, "@@server_id", output); | ||
| mysql_close(conn); | ||
|
|
||
| return std::string(output); | ||
| } | ||
|
|
||
| int main(int argc, char *argv[]) | ||
| { | ||
| TestConnections test(argc, argv); | ||
|
|
||
| char server_id[2][1024]; | ||
| test.repl->connect(); | ||
| std::string master = test.repl->get_server_id_str(0); | ||
| std::string slave = test.repl->get_server_id_str(1); | ||
| test.repl->close_connections(); | ||
|
|
||
| test.set_timeout(60); | ||
| test.add_result(do_query(test) != slave, "The slave should respond to the first query"); | ||
|
|
||
| pthread_t thr; | ||
| pthread_create(&thr, NULL, async_block, &test); | ||
| test.add_result(do_query(test) != master, "The master should respond to the second query"); | ||
| pthread_join(thr, NULL); | ||
| test.repl->unblock_node(1); | ||
|
|
||
| return test.global_result; | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| /** | ||
| * Test for MXS-1323. | ||
| * - Check that retried reads work with persistent connections | ||
| */ | ||
|
|
||
| #include "testconnections.h" | ||
| #include <sstream> | ||
|
|
||
| static bool running = true; | ||
|
|
||
| void* async_query(void* data) | ||
| { | ||
| TestConnections *test = (TestConnections*)data; | ||
|
|
||
| while (running && test->global_result == 0) | ||
| { | ||
| MYSQL* conn = test->open_rwsplit_connection(); | ||
|
|
||
| for (int i = 0; i < 50; i++) | ||
| { | ||
| const char* query = "SET @a = (SELECT SLEEP(1))"; | ||
| test->try_query(conn, query); | ||
| } | ||
|
|
||
| mysql_close(conn); | ||
| } | ||
|
|
||
| return NULL; | ||
| } | ||
|
|
||
| #define NUM_THR 5 | ||
|
|
||
| int main(int argc, char *argv[]) | ||
| { | ||
| TestConnections test(argc, argv); | ||
| pthread_t query_thr[NUM_THR]; | ||
| std::stringstream ss; | ||
|
|
||
| ss << "CREATE OR REPLACE TABLE test.t1 (id INT)"; | ||
| test.connect_maxscale(); | ||
| test.try_query(test.conn_rwsplit, ss.str().c_str()); | ||
|
|
||
| ss.str(""); | ||
| ss << "INSERT INTO test.t1 VALUES (0)"; | ||
| for (int i = 1; i <= 10000; i++) | ||
| { | ||
| ss << ",(" << i << ")"; | ||
| } | ||
| test.try_query(test.conn_rwsplit, ss.str().c_str()); | ||
|
|
||
| test.close_maxscale_connections(); | ||
|
|
||
| if (test.global_result) | ||
| { | ||
| return test.global_result; | ||
| } | ||
|
|
||
| for (int i = 0; i < NUM_THR; i++) | ||
| { | ||
| pthread_create(&query_thr[i], NULL, async_query, &test); | ||
| } | ||
|
|
||
| for (int i = 0; i < 3 && test.global_result == 0; i++) | ||
| { | ||
| test.tprintf("Round %d", i + 1); | ||
| test.repl->block_node(1); | ||
| sleep(5); | ||
| test.repl->unblock_node(1); | ||
| sleep(5); | ||
| } | ||
|
|
||
| running = false; | ||
|
|
||
| for (int i = 0; i < NUM_THR; i++) | ||
| { | ||
| test.set_timeout(10); | ||
| pthread_join(query_thr[i], NULL); | ||
| } | ||
|
|
||
| return test.global_result; | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters