Description:
If we look into trans_commit_stmt() and trans_commit_implicit() we will see that the result of tc_log->commit() is ignored, what leads to the following crash on debug build:
=====
#0 __pthread_kill (threadid=<optimized out>, signo=6) at ../sysdeps/unix/sysv/linux/pthread_kill.c:62
#1 0x0000000004530a69 in my_write_core (sig=6) at ./mysys/stacktrace.cc:278
#2 0x00000000031b430d in handle_fatal_signal (sig=6) at ./sql/signal_handler.cc:249
#3 <signal handler called>
#4 0x00007f4544411428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
#5 0x00007f454441302a in __GI_abort () at abort.c:89
#6 0x00007f4544409bd7 in __assert_fail_base (fmt=<optimized out>, assertion=assertion@entry=0x5595af0 "!is_set()", file=file@entry=0x5595910 "./sql/sql_error.cc", line=line@entry=379, function=function@entry=0x5595ea0 <Diagnostics_area::set_ok_status(unsigned long long, unsigned long long, char const*)::__PRETTY_FUNCTION__> "void Diagnostics_area::set_ok_status(ulonglong, ulonglong, const char*)") at assert.c:92
#7 0x00007f4544409c82 in __GI___assert_fail (assertion=0x5595af0 "!is_set()", file=0x5595910 "./sql/sql_error.cc", line=379, function=0x5595ea0 <Diagnostics_area::set_ok_status(unsigned long long, unsigned long long, char const*)::__PRETTY_FUNCTION__> "void Diagnostics_area::set_ok_status(ulonglong, ulonglong, const char*)") at assert.c:101
#8 0x0000000002f8e047 in Diagnostics_area::set_ok_status (this=0x7f448c029988, affected_rows=0, last_insert_id=0, message_text=0x0) at ./sql/sql_error.cc:379
#9 0x0000000002f851bd in my_ok (thd=0x7f448c027680, affected_rows=0, id=0, message=0x0) at ./sql/sql_class.h:4067
#10 0x0000000003094e38 in mysql_rm_table (thd=0x7f448c027680, tables=0x7f448c12c880, if_exists=false, drop_temporary=false) at ./sql/sql_table.cc:1528
#11 0x0000000002ff89ec in mysql_execute_command (thd=0x7f448c027680, first_level=true) at ./sql/sql_parse.cc:3336
#12 0x0000000002ffe4c4 in mysql_parse (thd=0x7f448c027680, parser_state=0x7f4538aa4380, force_primary_storage_engine=false) at ./sql/sql_parse.cc:5041
#13 0x0000000002ff3e0c in dispatch_command (thd=0x7f448c027680, com_data=0x7f4538aa4cf0, command=COM_QUERY) at ./sql/sql_parse.cc:1687
#14 0x0000000002ff246e in do_command (thd=0x7f448c027680) at ./sql/sql_parse.cc:1260
#15 0x000000000319fe59 in handle_connection (arg=0x7b609c0) at ./sql/conn_handler/connection_handler_per_thread.cc:308
#16 0x0000000004c263d0 in pfs_spawn_thread (arg=0x7bd2990) at ./storage/perfschema/pfs.cc:2836
#17 0x00007f454612e6ba in start_thread (arg=0x7f4538aa5700) at pthread_create.c:333
#18 0x00007f45444e341d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
=====
The assert fires because the diagnostics area error status was previously set from here:
=====
#0 Diagnostics_area::set_error_status (this=0x7fff48029988, mysql_errno=3100,
message_text=0x7fffe89fba30 "Error on observer while running replication hook 'before_commit'.", returned_sqlstate=0x5d1e714 "HY000")
at ./sql/sql_error.cc:426
#1 0x0000000002f662cc in THD::raise_condition (this=0x7fff48027680, sql_errno=3100, sqlstate=0x5d1e714 "HY000", level=Sql_condition::SL_ERROR,
msg=0x7fffe89fba30 "Error on observer while running replication hook 'before_commit'.", use_condition_handler=false)
at ./sql/sql_class.cc:717
#2 0x0000000002e67827 in my_message_sql (error=3100, str=0x7fffe89fba30 "Error on observer while running replication hook 'before_commit'.", MyFlags=0)
at ./sql/mysqld.cc:3017
#3 0x000000000451f1d8 in my_error (nr=3100, MyFlags=0) at ./mysys/my_error.cc:247
#4 0x0000000004124005 in MYSQL_BIN_LOG::commit (this=0x6d2ccc0 <mysql_bin_log>, thd=0x7fff48027680, all=false)
at ./sql/binlog.cc:7710
#5 0x000000000315c8f3 in trans_commit_stmt (thd=0x7fff48027680, ignore_global_read_lock=false) at ./sql/transaction.cc:483
#6 0x0000000003098a9d in mysql_rm_table_no_locks (thd=0x7fff48027680, tables=0x7fff482fa780, if_exists=false, drop_temporary=false, drop_database=false,
dropped_non_atomic_flag=0x7fffe89fdf11, post_ddl_htons=0x7fffe89fdf80, fk_invalidator=0x7fffe89fdfb0, safe_to_release_mdl=0x7fffe89fdf40)
at ./sql/sql_table.cc:3029
#7 0x0000000003094b82 in mysql_rm_table (thd=0x7fff48027680, tables=0x7fff482fa780, if_exists=false, drop_temporary=false)
at ./sql/sql_table.cc:1467
#8 0x0000000002ff89ec in mysql_execute_command (thd=0x7fff48027680, first_level=true) at ./sql/sql_parse.cc:3336
#9 0x0000000002ffe4c4 in mysql_parse (thd=0x7fff48027680, parser_state=0x7fffe89ff380, force_primary_storage_engine=false)
at ./sql/sql_parse.cc:5041
#10 0x0000000002ff3e0c in dispatch_command (thd=0x7fff48027680, com_data=0x7fffe89ffcf0, command=COM_QUERY)
at ./sql/sql_parse.cc:1687
#11 0x0000000002ff246e in do_command (thd=0x7fff48027680) at ./sql/sql_parse.cc:1260
#12 0x000000000319fe59 in handle_connection (arg=0x72fbd20) at ./sql/conn_handler/connection_handler_per_thread.cc:308
#13 0x0000000004c263d0 in pfs_spawn_thread (arg=0x72b8a00) at ./storage/perfschema/pfs.cc:2836
#14 0x00007ffff79be6ba in start_thread (arg=0x7fffe8a00700) at pthread_create.c:333
#15 0x00007ffff5d7341d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
=====
during DROP TABLE execution from the statements sequence, described in "How to repeat" section.
In other words, if, for example, there will be error on binlog commit, the error will be ignored, and the client will get "Error" status for the query execution on release build(as the status is not updated to "OK" on error, see Diagnostics_area::set_ok_status()), and crash on debug build.
How to repeat:
Execute the following queries sequence on debug build:
=====
CREATE TABLE t_myisam(a INT NOT NULL) ENGINE=Myisam;
SET @@GLOBAL.DEBUG= '+d,simulate_failure_in_before_commit_hook';
DROP TABLE test1.t_myisam;
=====
Suggested fix:
Return "error" from trans_commit_stmt() and trans_commit_implicit() if tc_log->commit returns error.