Details
Description
- run a long create table on con1;
- try to connect with MySQL client with enabled auto-rehash (the client hangs on Field List command), or somehow else initiate Field List;
- kill the new connection.
The test cases below use C test rather than MTR because there is no analogue for mysql_list_fields in MTR language, and there is no asynchronous system/exec call. Without either of those, an MTR test becomes ugly and unreliable.
Please also note that the test uses mysql_list_fields_start, so it should be linked with the library that has it.
The first test case is faster, but it requires CREATE OR REPLACE (which is not available before 10.0.8), and also uses the bug MDEV-5602, so it might stop being reproducible after the bug is fixed.
#include <my_global.h> #include <mysql.h> int main(int argc, char **argv) { MYSQL *con = mysql_init(NULL); MYSQL *con2 = mysql_init(NULL); MYSQL_RES *res; if (con == NULL) { fprintf(stderr, "%s\n", mysql_error(con)); exit(1); } if (con2 == NULL) { fprintf(stderr, "%s\n", mysql_error(con2)); exit(1); } if (mysql_real_connect(con, "127.0.0.1", "root", "", "test", 0, NULL, 0) == NULL) { fprintf(stderr, "%s\n", mysql_error(con)); mysql_close(con); exit(1); } mysql_query(con,"DROP TABLE IF EXISTS t1"); mysql_query(con,"CREATE TABLE t1 (i INT)"); mysql_query(con,"LOCK TABLE t1 WRITE"); mysql_query(con,"CREATE OR REPLACE TABLE t1 (i INT)"); if (mysql_real_connect(con2, "127.0.0.1", "root", "", "test", 0, NULL, 0) == NULL) { fprintf(stderr, "%s\n", mysql_error(con2)); mysql_close(con2); exit(1); } mysql_options(con2, MYSQL_OPT_NONBLOCK, 0); mysql_list_fields_start(&res,con2,(const char*) "t1",NullS); sleep(1); mysql_query(con,"SELECT ID INTO @kill_id FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND = 'Field List'"); mysql_query(con,"KILL @kill_id"); mysql_close(con2); mysql_close(con); exit(0); }
#6 0x00007fd6a3134621 in *__GI___assert_fail (assertion=0xec0d48 "0", file=<optimized out>, line=518, function=0xec2000 "void Protocol::end_statement()") at assert.c:81 #7 0x00000000005c448b in Protocol::end_statement (this=0x7fd67ea7a5f8) at /sql/protocol.cc:518 #8 0x000000000066863b in dispatch_command (command=COM_FIELD_LIST, thd=0x7fd67ea7a070, packet=0x7fd67ea80074 "", packet_length=3) at /sql/sql_parse.cc:1714 #9 0x00000000006665e4 in do_command (thd=0x7fd67ea7a070) at /sql/sql_parse.cc:993 #10 0x000000000077f619 in do_handle_one_connection (thd_arg=0x7fd67ea7a070) at /sql/sql_connect.cc:1379 #11 0x000000000077f36c in handle_one_connection (arg=0x7fd67ea7a070) at /sql/sql_connect.cc:1293 #12 0x0000000000a1f329 in pfs_spawn_thread (arg=0x7fd67ee4c8b0) at /storage/perfschema/pfs.cc:1853 #13 0x00007fd6a4cd8b50 in start_thread (arg=<optimized out>) at pthread_create.c:304 #14 0x00007fd6a31e3a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
revision-id: monty@askmonty.org-20140202093802-a6jtuy6ni29biigz revno: 3968 branch-nick: mariadb-monty
The second test case is considerably slower, but it can be run on any version, MariaDB or MySQL.
// gcc -c -I/data/repo/bzr/5.5/include/mysql -I/data/repo/bzr/5.5/include/mysql/.. test2.c && gcc -o test2 test2.o -L/data/repo/bzr/5.5/libmysql -lmysqlclient && ./test2 #include <my_global.h> #include <mysql.h> int main(int argc, char **argv) { MYSQL *con = mysql_init(NULL); MYSQL *con2 = mysql_init(NULL); MYSQL *con3 = mysql_init(NULL); int *res; MYSQL_RES *res2; if (mysql_real_connect(con, "127.0.0.1", "root", "", "test", 0, NULL, 0) == NULL) { fprintf(stderr, "%s\n", mysql_error(con)); mysql_close(con); exit(1); } mysql_query(con,"DROP TABLE IF EXISTS t1, t2"); mysql_query(con,"CREATE TABLE t1 (i INT) ENGINE=MyISAM"); mysql_query(con,"INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8)"); mysql_query(con,"INSERT INTO t1 SELECT a.* FROM t1 a, t1 b, t1 c, t1 d, t1 e, t1 f, t1 g"); mysql_options(con, MYSQL_OPT_NONBLOCK, 0); mysql_query_start(res,con,"CREATE TABLE t2 AS SELECT * FROM t1"); if (mysql_real_connect(con2, "127.0.0.1", "root", "", "test", 0, NULL, 0) == NULL) { fprintf(stderr, "%s\n", mysql_error(con2)); mysql_close(con2); exit(1); } mysql_options(con2, MYSQL_OPT_NONBLOCK, 0); mysql_list_fields_start(&res2,con2,(const char*) "t2",NullS); sleep(3); if (mysql_real_connect(con3, "127.0.0.1", "root", "", "test", 0, NULL, 0) == NULL) { fprintf(stderr, "%s\n", mysql_error(con3)); mysql_close(con3); exit(1); } mysql_query(con3,"SELECT ID INTO @kill_id FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND = 'Field List'"); mysql_query(con3,"KILL @kill_id"); mysql_close(con3); mysql_close(con2); mysql_close(con); exit(0); }
The problem is also reproducible on MySQL 5.5, but not on MySQL 5.6, so possibly it will eventually go away from 10.0 along with the merge of MySQL 5.6 bugfixes.
Gliffy Diagrams
Attachments
Activity
- All
- Comments
- Work Log
- History
- Activity
- Transitions
Found a way to reproduce without CREATE OR REPLACE, assigning back to myself to modify the test case.