
See script directory for method. The script to run in the top level MaxScale directory is called maxscale-uncrustify.sh, which uses another script, list-src, from the same directory (so you need to set your PATH). The uncrustify version was 0.66.
224 lines
7.6 KiB
C++
224 lines
7.6 KiB
C++
/**
|
|
* @file bug643.cpp regression case for bugs 645 ("Tee filter with readwritesplit service hangs MaxScale")
|
|
* - setup RWSplit in the following way
|
|
* @verbatim
|
|
* [RW_Router]
|
|
* type=service
|
|
* router=readconnroute
|
|
* servers=server1
|
|
* user=skysql
|
|
* passwd=skysql
|
|
* version_string=5.1-OLD-Bored-Mysql
|
|
* filters=DuplicaFilter
|
|
*
|
|
* [RW_Split]
|
|
* type=service
|
|
* router=readwritesplit
|
|
* servers=server1, server3,server2
|
|
* user=skysql
|
|
* passwd=skysql
|
|
*
|
|
* [DuplicaFilter]
|
|
* type=filter
|
|
* module=tee
|
|
* service=RW_Split
|
|
*
|
|
* [RW_Listener]
|
|
* type=listener
|
|
* service=RW_Router
|
|
* protocol=MySQLClient
|
|
* port=4006
|
|
*
|
|
* [RW_Split_list]
|
|
* type=listener
|
|
* service=RW_Split
|
|
* protocol=MySQLClient
|
|
* port=4016
|
|
*
|
|
* @endverbatim
|
|
* - try to connect
|
|
* - try simple query
|
|
* - check MaxScale is alive
|
|
*/
|
|
|
|
/*
|
|
* Massimiliano 2014-12-11 14:19:51 UTC
|
|
* When tee filter is used with a readwritesplit service MaxScale hangs (each service including admin
|
|
* interface)or there is a failed assetion in Debug mode:
|
|
*
|
|
* debug assert /source/GA/server/modules/routing/readwritesplit/readwritesplit.c:1825
|
|
* maxscale: /source/GA/server/modules/routing/readwritesplit/readwritesplit.c:1825: routeQuery: Assertion
|
|
* `!(querybuf->gwbuf_type == 0)' failed.
|
|
*
|
|
*
|
|
* Configuration:
|
|
*
|
|
*
|
|
* [RW_Router]
|
|
* type=service
|
|
* router=readconnroute
|
|
* servers=server1
|
|
* user=massi
|
|
* passwd=massi
|
|
* version_string=5.1-OLD-Bored-Mysql
|
|
* filters=DuplicaFilter
|
|
*
|
|
* [RW_Split]
|
|
* type=service
|
|
* router=readwritesplit
|
|
* servers=server3,server2
|
|
* user=massi
|
|
* passwd=massi
|
|
*
|
|
* [DuplicaFilter]
|
|
* type=filter
|
|
* module=tee
|
|
* service=RW_Split
|
|
*
|
|
* [RW_Listener]
|
|
* type=listener
|
|
* service=RW_Router
|
|
* protocol=MySQLClient
|
|
* port=4606
|
|
*
|
|
*
|
|
* Accessing the RW_listener:
|
|
*
|
|
* mysql -h 127.0.0.1 -P 4606 -umassi -pmassi
|
|
*
|
|
*
|
|
*
|
|
* Debug version:
|
|
*
|
|
* 2014-12-11 08:48:48 Fatal: MaxScale received fatal signal 6. Attempting backtrace.
|
|
* 2014-12-11 08:48:48 ./maxscale() [0x53c80e]
|
|
* 2014-12-11 08:48:48 /lib64/libpthread.so.0(+0xf710) [0x7fd418a62710]
|
|
* 2014-12-11 08:48:48 /lib64/libc.so.6(gsignal+0x35) [0x7fd417318925]
|
|
* 2014-12-11 08:48:48 /lib64/libc.so.6(abort+0x175) [0x7fd41731a105]
|
|
* 2014-12-11 08:48:48 /lib64/libc.so.6(+0x2ba4e) [0x7fd417311a4e]
|
|
* 2014-12-11 08:48:48 /lib64/libc.so.6(__assert_perror_fail+0) [0x7fd417311b10]
|
|
* 2014-12-11 08:48:48 /usr/local/skysql/maxscale/modules/libreadwritesplit.so(+0x69ca) [0x7fd4142789ca]
|
|
* 2014-12-11 08:48:48 /usr/local/skysql/maxscale/modules/libtee.so(+0x3707) [0x7fd3fc2db707]
|
|
* 2014-12-11 08:48:48 /usr/local/skysql/maxscale/modules/libMySQLClient.so(+0x595d) [0x7fd3fe34b95d]
|
|
* 2014-12-11 08:48:48 ./maxscale() [0x54d3ec]
|
|
* 2014-12-11 08:48:48 ./maxscale(poll_waitevents+0x63d) [0x54ca8a]
|
|
* 2014-12-11 08:48:48 ./maxscale(main+0x1acc) [0x53f616]
|
|
* 2014-12-11 08:48:48 /lib64/libc.so.6(__libc_start_main+0xfd) [0x7fd417304d1d]
|
|
* 2014-12-11 08:48:48 ./maxscale() [0x53a92d]
|
|
*
|
|
*
|
|
* Without debug:
|
|
*
|
|
* we got mysql prompt but then maxscale is stucked
|
|
* or
|
|
* when don't have the prompt, it hangs after few welcome messages
|
|
* Comment 1 Vilho Raatikka 2014-12-11 15:14:50 UTC
|
|
* The assertion occurs because query is is not statement - but packet type. That is, it was sent to read
|
|
* connection router which doesn't examine MySQL packets except the header. Thus, the type of query is not set
|
|
* in mysql_client.c:gw_read_client_event:
|
|
* >>>
|
|
* if (cap == 0 || (cap == RCAP_TYPE_PACKET_INPUT))
|
|
* {
|
|
* stmt_input = false;
|
|
* }
|
|
* else if (cap == RCAP_TYPE_STMT_INPUT)
|
|
* {
|
|
* stmt_input = true;
|
|
*
|
|
* gwbuf_set_type(read_buffer, GWBUF_TYPE_MYSQL);
|
|
* }
|
|
* >>>
|
|
* Comment 2 Massimiliano 2014-12-11 16:00:52 UTC
|
|
* Using readconnroute (with router_options=master) instead seems fine.
|
|
*
|
|
* I found that "USE dbname" is not passed via tee filter:
|
|
*
|
|
*
|
|
* 4606 is the listener to a service with tee filter
|
|
*
|
|
* root@maxscale-02 build]# mysql -h 127.0.0.1 -P 4606 -u massi -pmassi
|
|
*
|
|
*
|
|
*
|
|
* USE test; SELECT DATABASE()
|
|
* client to maxscale:
|
|
*
|
|
* T 127.0.0.1:40440 -> 127.0.0.1:4606 [AP]
|
|
* 05 00 00 00 02 74 65 73 74 .....test
|
|
*
|
|
* T 127.0.0.1:4606 -> 127.0.0.1:40440 [AP]
|
|
* 07 00 00 01 00 00 00 02 00 00 00 ...........
|
|
*
|
|
* T 127.0.0.1:40440 -> 127.0.0.1:4606 [AP]
|
|
* 12 00 00 00 03 53 45 4c 45 43 54 20 44 41 54 41 .....SELECT DATA
|
|
* 42 41 53 45 28 29 BASE()
|
|
*
|
|
* T 127.0.0.1:4606 -> 127.0.0.1:40440 [AP]
|
|
* 01 00 00 01 01 20 00 00 02 03 64 65 66 00 00 00 ..... ....def...
|
|
* 0a 44 41 54 41 42 41 53 45 28 29 00 0c 08 00 22 .DATABASE()...."
|
|
* 00 00 00 fd 00 00 1f 00 00 05 00 00 03 fe 00 00 ................
|
|
* 02 00 05 00 00 04 04 74 65 73 74 05 00 00 05 fe .......test.....
|
|
* 00 00 02 00 ....
|
|
*
|
|
* maxscale to backend:
|
|
*
|
|
*
|
|
* T 127.0.0.1:56578 -> 127.0.0.1:3308 [AP]
|
|
* 12 00 00 00 03 53 45 4c 45 43 54 20 44 41 54 41 .....SELECT DATA
|
|
* 42 41 53 45 28 29 BASE()
|
|
*
|
|
* T 127.0.0.1:3308 -> 127.0.0.1:56578 [AP]
|
|
* 01 00 00 01 01 20 00 00 02 03 64 65 66 00 00 00 ..... ....def...
|
|
* 0a 44 41 54 41 42 41 53 45 28 29 00 0c 08 00 22 .DATABASE()...."
|
|
* 00 00 00 fd 00 00 1f 00 00 05 00 00 03 fe 00 00 ................
|
|
* 02 00 01 00 00 04 fb 05 00 00 05 fe 00 00 02 00 ................
|
|
*
|
|
*
|
|
* USE test was not sent
|
|
*
|
|
*
|
|
*
|
|
* May be a similar issue is present with readwritesplit but I cannot test it
|
|
* Comment 3 Vilho Raatikka 2014-12-11 16:35:46 UTC
|
|
* (In reply to comment #2)
|
|
* > Using readconnroute (with router_options=master) instead seems fine.
|
|
*
|
|
* Using readconnroute _where_? in tee?
|
|
* Comment 4 Vilho Raatikka 2014-12-12 08:27:41 UTC
|
|
* gwbuf_type is not set and that is the immediate cause for assertion with Debug version.
|
|
* Reason why the type is not set is in the way the packets are first processed in mysql_client.c client
|
|
* protocol module and then passed optionally to filters and router. There is a bug because it is assumed that
|
|
* when client protocol module reads incoming packet it can resolve which router will handle the packet
|
|
* processing. The code doesn't take into account that same packet can be processed by many different
|
|
* maxscales->routers[0], like in the case of readconnrouter->tee->readwritesplit.
|
|
* Another problem is in readwritesplit where it is assumed that it is the first and the only router that
|
|
* will process tha data. So it includes checks that the buffer has correct type.
|
|
*
|
|
* Required changes are:
|
|
* - readwritesplit should check if buffer has no type and in that case, insted of asserting, merge incoming
|
|
* MySQL packet fragments into a single contiguous buffer.
|
|
* - remove checks which enforce rules which are based on false assumption.
|
|
*/
|
|
|
|
|
|
#include <iostream>
|
|
#include "testconnections.h"
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
TestConnections* Test = new TestConnections(argc, argv);
|
|
Test->set_timeout(10);
|
|
|
|
Test->maxscales->connect_maxscale(0);
|
|
Test->try_query(Test->maxscales->conn_master[0], (char*) "show processlist");
|
|
Test->try_query(Test->maxscales->conn_slave[0], (char*) "show processlist");
|
|
Test->try_query(Test->maxscales->conn_rwsplit[0], (char*) "show processlist");
|
|
Test->maxscales->close_maxscale_connections(0);
|
|
|
|
Test->check_maxscale_alive(0);
|
|
|
|
int rval = Test->global_result;
|
|
delete Test;
|
|
return rval;
|
|
}
|