Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-5603

Assertion `0' fails on killing a connection waiting for a lock

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 5.5.35, 10.0.7
    • Fix Version/s: 10.0.16
    • Component/s: OTHER
    • Labels:

      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

            Hide
            elenst Elena Stepanova added a comment -

            Found a way to reproduce without CREATE OR REPLACE, assigning back to myself to modify the test case.

            Show
            elenst Elena Stepanova added a comment - Found a way to reproduce without CREATE OR REPLACE, assigning back to myself to modify the test case.
            Hide
            elenst Elena Stepanova added a comment - - edited

            Still reproducible on 5.5.40+, 10.0.14+.

            I'm setting it to upstream-fixed and raising the priority even though there is no linked upstream bug, because the problem is reproducible on MySQL 5.5 but not on 5.6/5.7 (so, no point filing a bug upstream). And since we are not merging bugfixes automatically, there is little chance that it will go away on its own.

            Show
            elenst Elena Stepanova added a comment - - edited Still reproducible on 5.5.40+, 10.0.14+. I'm setting it to upstream-fixed and raising the priority even though there is no linked upstream bug, because the problem is reproducible on MySQL 5.5 but not on 5.6/5.7 (so, no point filing a bug upstream). And since we are not merging bugfixes automatically, there is little chance that it will go away on its own.
            Hide
            serg Sergei Golubchik added a comment - - edited

            I failed to repeat it using your instructions on the latest 10.0 from github:

            • start two mysql command-line clients
            • in the first start a long-running create table
            • start yet another mysql command-line client in another terminal window, it hangs
            • in the remaining mysql command-line client KILL the hanging connection
            Show
            serg Sergei Golubchik added a comment - - edited I failed to repeat it using your instructions on the latest 10.0 from github: start two mysql command-line clients in the first start a long-running create table start yet another mysql command-line client in another terminal window, it hangs in the remaining mysql command-line client KILL the hanging connection
            Hide
            elenst Elena Stepanova added a comment -

            The problem disappeared from 10.0 tree from the following revision:

            revno: 4573
            revision-id: sergii@pisem.net-20150119131914-2h0sd0988be6czxd
            parent: sergii@pisem.net-20150119131905-zjcvewlb9dw85two
            fixes bug: https://mariadb.atlassian.net/browse/MDEV-7299
            committer: Sergei Golubchik <sergii@pisem.net>
            branch nick: 10.0
            timestamp: Mon 2015-01-19 14:19:14 +0100
            message:
              MDEV-7299 Assertion `m_status == DA_ERROR || m_status == DA_OK' fails on concurrent execution of DDL, queries from I_S, and KILL QUERY
              
              Fix MDL to report an error when a wait was killed, but preserve
              the old documented behavior of GET_LOCK() where killing it is not an error.
              
              Also remove race conditions in main.create_or_replace test
            
            Show
            elenst Elena Stepanova added a comment - The problem disappeared from 10.0 tree from the following revision: revno: 4573 revision-id: sergii@pisem.net-20150119131914-2h0sd0988be6czxd parent: sergii@pisem.net-20150119131905-zjcvewlb9dw85two fixes bug: https://mariadb.atlassian.net/browse/MDEV-7299 committer: Sergei Golubchik <sergii@pisem.net> branch nick: 10.0 timestamp: Mon 2015-01-19 14:19:14 +0100 message: MDEV-7299 Assertion `m_status == DA_ERROR || m_status == DA_OK' fails on concurrent execution of DDL, queries from I_S, and KILL QUERY Fix MDL to report an error when a wait was killed, but preserve the old documented behavior of GET_LOCK() where killing it is not an error. Also remove race conditions in main.create_or_replace test

              People

              • Assignee:
                serg Sergei Golubchik
                Reporter:
                elenst Elena Stepanova
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: