Bug #54812 assert in Diagnostics_area::set_ok_status during EXPLAIN
Submitted: 25 Jun 2010 14:58 Modified: 6 Jan 2011 2:40
Reporter: Matthias Leich Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S3 (Non-critical)
Version:5.1, 5.5 OS:Any
Assigned to: Jørgen Løland CPU Architecture:Any

[25 Jun 2010 14:58] Matthias Leich
Description:
The assert happens in sql_error.cc:360 :
void
Diagnostics_area::set_ok_status(THD *thd, ulonglong affected_rows_arg,
                                ulonglong last_insert_id_arg,
                                const char *message_arg)
{
  DBUG_ENTER("set_ok_status");
  DBUG_ASSERT(! is_set());   <-------------------------
  /*
    In production, refuse to overwrite an error or a custom response
    with an OK packet.
  */

RQG test with concurrent DDL/DML workload
- 32 threads
- current conf/runtime/WL5004_* grammars

Result on 5.5.5-m3-debug-log mysql-trunk-runtime revno: 3062 2010-06-25
-----------------------------------------------------------------------
Thread 1 (Thread 10882):
#0  0x000000382860bd02 in pthread_kill () from /lib64/libpthread.so.0
#1  0x0000000000b5b191 in my_write_core (sig=6) at stacktrace.c:326
#2  0x0000000000699e71 in handle_segfault (sig=6) at mysqld.cc:2791
#3  <signal handler called>
#4  0x0000003827a30265 in raise () from /lib64/libc.so.6
#5  0x0000003827a31d10 in abort () from /lib64/libc.so.6
#6  0x0000003827a296e6 in __assert_fail () from /lib64/libc.so.6
#7  0x0000000000765e52 in Diagnostics_area::set_ok_status (
    this=0x2aaab81d6dc0, thd=0x2aaab81d42f8, affected_rows_arg=0,
    last_insert_id_arg=0, message_arg=0x0) at sql_error.cc:360
#8  0x00000000005a468e in my_ok (thd=0x2aaab81d42f8, affected_rows=0, id=0,
    message=0x0) at sql_class.h:2750
#9  0x000000000067bb70 in select_dumpvar::send_eof (this=0x2aaab40c1990)
    at sql_class.cc:2890
#10 0x0000000000748f7e in JOIN::exec (this=0x2aaab7bfbf78)
    at sql_select.cc:1844
#11 0x0000000000745add in mysql_select (thd=0x2aaab81d42f8,
    rref_pointer_array=0x2aaab40c0db0, tables=0x2aaab4060138, wild_num=0,
    fields=..., conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0,
    proc_param=0x0, select_options=2147748608, result=0x2aaab40c1990,
    unit=0x2aaab40c05e0, select_lex=0x2aaab40c0be0) at sql_select.cc:2549
#12 0x000000000074b207 in handle_select (thd=0x2aaab81d42f8,
    lex=0x2aaab40c0538, result=0x2aaab40c1990, setup_tables_done_option=0)
    at sql_select.cc:290
#13 0x00000000006aae58 in execute_sqlcom_select (thd=0x2aaab81d42f8,
    all_tables=0x2aaab4060138) at sql_parse.cc:4882
#14 0x00000000006abf05 in mysql_execute_command (thd=0x2aaab81d42f8)
    at sql_parse.cc:2329
#15 0x000000000089701d in sp_instr_stmt::exec_core (this=0x2aaab40c1a08,
    thd=0x2aaab81d42f8, nextp=0x4a0c71d8) at sp_head.cc:2989
#16 0x00000000008979c6 in sp_lex_keeper::reset_lex_and_exec_core (
    this=0x2aaab40c1a48, thd=0x2aaab81d42f8, nextp=0x4a0c71d8,
    open_tables=false, instr=0x2aaab40c1a08) at sp_head.cc:2805
#17 0x0000000000898057 in sp_instr_stmt::execute (this=0x2aaab40c1a08,
    thd=0x2aaab81d42f8, nextp=0x4a0c71d8) at sp_head.cc:2926
#18 0x000000000089a400 in sp_head::execute (this=0x2aaab40bfcb8,
    thd=0x2aaab81d42f8) at sp_head.cc:1290
#19 0x000000000089bb0e in sp_head::execute_function (this=0x2aaab40bfcb8,
    thd=0x2aaab81d42f8, argp=0x8f8f8f8f8f8f8f8f, argcount=0, return_value_fld=
    0x2aaab408fdd0) at sp_head.cc:1816
#20 0x00000000005e7310 in Item_func_sp::execute_impl (this=0x925b050,
    thd=0x2aaab81d42f8) at item_func.cc:6287
#21 0x00000000005e7384 in Item_func_sp::execute (this=0x925b050)
    at item_func.cc:6216
#22 0x00000000005fb44f in Item_func_sp::val_int (this=0x925b050)
    at item_func.h:1723
#23 0x00000000005fca8c in Arg_comparator::compare_int_signed (this=0x925bec8)
    at item_cmpfunc.cc:1463
#24 0x00000000005dedff in Arg_comparator::compare (this=0x925bec8)
    at item_cmpfunc.h:87
#25 0x00000000006010fd in Item_func_eq::val_int (this=0x925be18)
    at item_cmpfunc.cc:1870
#26 0x0000000000732ed9 in make_join_select (join=0x2aaab408e3c8,
    select=0x2aaab4090b78, cond=0x925c288) at sql_select.cc:6363
#27 0x0000000000742088 in JOIN::optimize (this=0x2aaab408e3c8)
    at sql_select.cc:1165
#28 0x0000000000745a41 in mysql_select (thd=0x2aaab81d42f8,
    rref_pointer_array=0x2aaab81d6460, tables=0x925a918, wild_num=0,
    fields=..., conds=0x925c288, og_num=0, order=0x0, group=0x0, having=0x0,
    proc_param=0x0, select_options=2147748612, result=0x2aaab4048168,
    unit=0x2aaab81d5c90, select_lex=0x2aaab81d6290) at sql_select.cc:2535
#29 0x0000000000745fb5 in mysql_explain_union (thd=0x2aaab81d42f8,
    unit=0x2aaab81d5c90, result=0x2aaab4048168) at sql_select.cc:17041
#30 0x00000000006aacaf in execute_sqlcom_select (thd=0x2aaab81d42f8,
    all_tables=0x925a918) at sql_parse.cc:4860
#31 0x00000000006abf05 in mysql_execute_command (thd=0x2aaab81d42f8)
    at sql_parse.cc:2329
#32 0x00000000006b3577 in mysql_parse (thd=0x2aaab81d42f8,
    inBuf=0x925a3c8 "EXPLAIN /*!50100 PARTITIONS */ SELECT   `col_int_key` , `col_int` , `pk`  FROM testdb_S . t1_temp1_N  AS A WHERE testdb_N . f1_2_N  () = 1 AND `pk` = 6", length=151, parser_state=0x4a0c99b0) at sql_parse.cc:5911
#33 0x00000000006b4b2a in dispatch_command (command=COM_QUERY,
    thd=0x2aaab81d42f8, packet=0x2aaab821f8e9 "", packet_length=154)
    at sql_parse.cc:1135
#34 0x00000000006b6072 in do_command (thd=0x2aaab81d42f8) at sql_parse.cc:807
#35 0x00000000006a3f81 in do_handle_one_connection (thd_arg=0x2aaab81d42f8)
    at sql_connect.cc:1196
#36 0x00000000006a4047 in handle_one_connection (arg=0x2aaab81d42f8)
    at sql_connect.cc:1135
#37 0x000000382860673d in start_thread () from /lib64/libpthread.so.0
#38 0x0000003827ad3d1d in clone () from /lib64/libc.so.6

How to repeat:
I will upload an archive with log and grammars.
The crash has a low probability.
Please wait till I come up with a simplified
replay testcase.
[25 Jun 2010 15:03] Matthias Leich
Archive with log and grammars

Attachment: problem.tgz (application/x-compressed-tar, text), 88.65 KiB.

[9 Nov 2010 9:09] Jørgen Løland
Encountered a very similar trace with the WL5004_sql.yy grammar. Command used to test:

./runall.pl 
--mem 
--grammar=conf/runtime/WL5004_sql.yy 
--gendata=conf/runtime/WL5004_data.zz 
--basedir=/mysql/mysql-5.5-runtime
--queries=10M 
--duration=36000 
--threads=30 
--reporter=Deadlock,Backtrace,Shutdown 
--mysqld=--lock-wait-timeout=1

Trace:
------
#8  0xb7444648 in *__GI___assert_fail (assertion=0x86fdad5 "! is_set()", 
    file=0x86fd9f0 "mysql/mysql-5.5-runtime/sql/sql_error.cc", line=360, 
    function=0x86fe060 "void Diagnostics_area::set_ok_status(THD*, ulonglong, ulonglong, const char*)") at assert.c:81
#9  0x081f1bec in Diagnostics_area::set_ok_status (this=0xa690dd3c, thd=0xa690bfc0, affected_rows_arg=0, 
    last_insert_id_arg=0, message_arg=0x0) at mysql/mysql-5.5-runtime/sql/sql_error.cc:360
#10 0x081b6571 in my_ok (thd=0xa690bfc0, affected_rows=0, id=0, message=0x0)
    at mysql/mysql-5.5-runtime/sql/sql_class.h:2767
#11 0x081e34c8 in select_dumpvar::send_eof (this=0xb096dd8)
    at mysql/mysql-5.5-runtime/sql/sql_class.cc:2926
#12 0x0823f32a in JOIN::exec (this=0xa5daefa0) at mysql/mysql-5.5-runtime/sql/sql_select.cc:1869
#13 0x0824165a in mysql_select (thd=0xa690bfc0, rref_pointer_array=0xb0962f4, tables=0xb096a30, wild_num=0, 
    fields=..., conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2147486464, 
    result=0xb096dd8, unit=0xb095dc4, select_lex=0xb0961fc)
    at mysql/mysql-5.5-runtime/sql/sql_select.cc:2560
#14 0x0823a620 in handle_select (thd=0xa690bfc0, lex=0xb095d60, result=0xb096dd8, setup_tables_done_option=0)
    at mysql/mysql-5.5-runtime/sql/sql_select.cc:297
#15 0x08216d83 in execute_sqlcom_select (thd=0xa690bfc0, all_tables=0xb096a30)
    at mysql/mysql-5.5-runtime/sql/sql_parse.cc:4485
#16 0x0820f077 in mysql_execute_command (thd=0xa690bfc0)
    at mysql/mysql-5.5-runtime/sql/sql_parse.cc:2081
#17 0x0847ea63 in sp_instr_stmt::exec_core (this=0xb096e20, thd=0xa690bfc0, nextp=0xa6b08510)
    at mysql/mysql-5.5-runtime/sql/sp_head.cc:3159
#18 0x0847e29d in sp_lex_keeper::reset_lex_and_exec_core (this=0xb096e48, thd=0xa690bfc0, nextp=0xa6b08510, 
    open_tables=false, instr=0xb096e20) at mysql/mysql-5.5-runtime/sql/sp_head.cc:2957
[9 Nov 2010 9:12] Jørgen Løland
(continued - query that fails)
...
#33 0x08218e08 in mysql_parse (thd=0xa690bfc0, 
    rawbuf=0xb1745d0 "REPLACE  INTO testdb_N . t1_view1_N  ( `col_int_key` , `pk` , `col_int`  ) SELECT   `col_int_key` , `pk` , `col_int`  FROM testdb_S . t1_base2_S  AS A WHERE testdb_N . f1_2_N  () = 6 AND `pk` = 3 LIMI"...,
[11 Nov 2010 12:07] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/123597

3120 Jorgen Loland	2010-11-11
      Bug#54812: assert in Diagnostics_area::set_ok_status 
                 during EXPLAIN
      
      Before the patch, send_eof() of some subclasses of 
      select_result (e.g., select_send::send_eof()) could 
      handle being called after an error had occured while others 
      could not. 
      
      In the bug, an ASSERT triggered because 
      select_dumpvar::send_eof() was not well behaved after an 
      error had occured, but the problem also applied to other 
      subclasses of select_result. This patch uniforms send_eof() 
      of all subclasses of select_result to handle being called 
      after an error has occured. 
     @ mysql-test/r/errors.result
        Add test for BUG#54812
     @ mysql-test/t/errors.test
        Add test for BUG#54812
     @ sql/sql_class.cc
        Make send_eof() of all subclasses of select_result handle being
        called after an error has occured.
     @ sql/sql_insert.cc
        Make send_eof() of all subclasses of select_result handle being
        called after an error has occured.
     @ sql/sql_update.cc
        Make send_eof() of all subclasses of select_result handle being
        called after an error has occured.
[11 Nov 2010 15:13] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/123634

3120 Jorgen Loland	2010-11-11
      Bug#54812: assert in Diagnostics_area::set_ok_status 
                 during EXPLAIN
      
      Before the patch, send_eof() of some subclasses of 
      select_result (e.g., select_send::send_eof()) could 
      handle being called after an error had occured while others 
      could not. The methods that were not well-behaved would trigger
      an ASSERT on debug builds. Release builds were not affected.
      
      In the bug, an ASSERT triggered because 
      select_dumpvar::send_eof() was not well behaved after an 
      error had occured, but the problem also applied to other 
      subclasses of select_result. This patch uniforms send_eof() 
      of all subclasses of select_result to handle being called 
      after an error has occured. 
     @ sql/sql_class.cc
        Make send_eof() of all subclasses of select_result handle being
        called after an error has occured.
     @ sql/sql_insert.cc
        Make send_eof() of all subclasses of select_result handle being
        called after an error has occured.
     @ sql/sql_prepare.cc
        Make send_eof() of all subclasses of select_result handle being
        called after an error has occured.
     @ sql/sql_update.cc
        Make send_eof() of all subclasses of select_result handle being
        called after an error has occured.
[11 Nov 2010 15:25] Jon Olav Hauglid
Patch approved with minor comments discussed on IRC.
[11 Nov 2010 15:32] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/123639

3120 Jorgen Loland	2010-11-11
      Bug#54812: assert in Diagnostics_area::set_ok_status 
                 during EXPLAIN
      
      Before the patch, send_eof() of some subclasses of 
      select_result (e.g., select_send::send_eof()) could 
      handle being called after an error had occured while others 
      could not. The methods that were not well-behaved would trigger
      an ASSERT on debug builds. Release builds were not affected.
      
      Consider the following query as an example for how the ASSERT
      could be triggered:
      
      A user without execute privilege on f() does
         SELECT MAX(key1) INTO @dummy FROM t1 WHERE f() < 1;
      resulting in "ERROR 42000: execute command denied to user..." 
      
      The server would end the query by calling send_eof(). The 
      fact that the error had occured would make the ASSERT trigger. 
      
      select_dumpvar::send_eof() was the offending method in the
      bug report, but the problem also applied to other 
      subclasses of select_result. This patch uniforms send_eof() 
      of all subclasses of select_result to handle being called 
      after an error has occured. 
     @ mysql-test/r/not_embedded_server.result
        Added test for BUG#54812
     @ mysql-test/t/not_embedded_server.test
        Added test for BUG#54812
     @ sql/sql_class.cc
        Make send_eof() of all subclasses of select_result handle being
        called after an error has occured.
     @ sql/sql_insert.cc
        Make send_eof() of all subclasses of select_result handle being
        called after an error has occured.
     @ sql/sql_prepare.cc
        Make send_eof() of all subclasses of select_result handle being
        called after an error has occured.
     @ sql/sql_update.cc
        Make send_eof() of all subclasses of select_result handle being
        called after an error has occured.
[12 Nov 2010 13:41] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/123727

3121 Jorgen Loland	2010-11-12
      Bug#54812: assert in Diagnostics_area::set_ok_status 
                 during EXPLAIN
      
      Before the patch, send_eof() of some subclasses of 
      select_result (e.g., select_send::send_eof()) could 
      handle being called after an error had occured while others 
      could not. The methods that were not well-behaved would trigger
      an ASSERT on debug builds. Release builds were not affected.
      
      Consider the following query as an example for how the ASSERT
      could be triggered:
      
      A user without execute privilege on f() does
         SELECT MAX(key1) INTO @dummy FROM t1 WHERE f() < 1;
      resulting in "ERROR 42000: execute command denied to user..." 
      
      The server would end the query by calling send_eof(). The 
      fact that the error had occured would make the ASSERT trigger. 
      
      select_dumpvar::send_eof() was the offending method in the
      bug report, but the problem also applied to other 
      subclasses of select_result. This patch uniforms send_eof() 
      of all subclasses of select_result to handle being called 
      after an error has occured. 
     @ mysql-test/r/not_embedded_server.result
        Added test for BUG#54812
     @ mysql-test/t/not_embedded_server.test
        Added test for BUG#54812
     @ sql/sql_class.cc
        send_eof() of all subclasses of select_result can now handle being
        called after an error has occured.
     @ sql/sql_insert.cc
        send_eof() of all subclasses of select_result can now handle being
        called after an error has occured.
     @ sql/sql_prepare.cc
        send_eof() of all subclasses of select_result can now handle being
        called after an error has occured.
     @ sql/sql_update.cc
        send_eof() of all subclasses of select_result can now handle being
        called after an error has occured.
[15 Nov 2010 15:18] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/123928

3124 Jorgen Loland	2010-11-15
      Bug#54812: assert in Diagnostics_area::set_ok_status 
                 during EXPLAIN
      
      Before the patch, send_eof() of some subclasses of 
      select_result (e.g., select_send::send_eof()) could 
      handle being called after an error had occured while others 
      could not. The methods that were not well-behaved would trigger
      an ASSERT on debug builds. Release builds were not affected.
      
      Consider the following query as an example for how the ASSERT
      could be triggered:
      
      A user without execute privilege on f() does
         SELECT MAX(key1) INTO @dummy FROM t1 WHERE f() < 1;
      resulting in "ERROR 42000: execute command denied to user..." 
      
      The server would end the query by calling send_eof(). The 
      fact that the error had occured would make the ASSERT trigger. 
      
      select_dumpvar::send_eof() was the offending method in the
      bug report, but the problem also applied to other 
      subclasses of select_result. This patch uniforms send_eof() 
      of all subclasses of select_result to handle being called 
      after an error has occured. 
     @ mysql-test/r/not_embedded_server.result
        Added test for BUG#54812
     @ mysql-test/t/not_embedded_server.test
        Added test for BUG#54812
     @ sql/sql_class.cc
        send_eof() of all subclasses of select_result can now handle being
        called after an error has occured.
     @ sql/sql_insert.cc
        send_eof() of all subclasses of select_result can now handle being
        called after an error has occured.
        Also fix call to abort() in select_create::send_eof(), which was supposed to abort the result set, not terminate the server. This call to abort() should have been changed when the function was renamed from abort_result_set() but was forgotten. New test case added by BUG#54812 covered this line and terminated server.
     @ sql/sql_prepare.cc
        send_eof() of all subclasses of select_result can now handle being
        called after an error has occured.
     @ sql/sql_update.cc
        send_eof() of all subclasses of select_result can now handle being
        called after an error has occured.
[15 Nov 2010 15:35] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/123932

3341 Jorgen Loland	2010-11-15 [merge]
      Merge BUG#54812 from 5.5-bugteam to trunk-bugfixing. No conflicts.
[15 Nov 2010 15:37] Jørgen Løland
Pushed to 5.5-bugteam, merged to trunk-bugfixing
[5 Dec 2010 12:41] Bugs System
Pushed into mysql-trunk 5.6.1 (revid:alexander.nozdrin@oracle.com-20101205122447-6x94l4fmslpbttxj) (version source revid:alexander.nozdrin@oracle.com-20101205122447-6x94l4fmslpbttxj) (merge vers: 5.6.1) (pib:23)
[16 Dec 2010 22:31] Bugs System
Pushed into mysql-5.5 5.5.9 (revid:jonathan.perkin@oracle.com-20101216101358-fyzr1epq95a3yett) (version source revid:jonathan.perkin@oracle.com-20101216101358-fyzr1epq95a3yett) (merge vers: 5.5.9) (pib:24)
[6 Jan 2011 2:40] Paul DuBois
Noted in 5.5.8 changelog.

In debug builds, an assertion could be raised if a send_eof() method
was called after an error occurred.