Bug #11633 MySQL does not call ::external_lock in SHOW TABLE STATUS: a DROP may crash?
Submitted: 29 Jun 2005 8:32 Modified: 29 Jul 2005 8:24
Reporter: Vadim Tkachenko Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:5.0.8, 5.0.9 OS:
Assigned to: Sergei Glukhov CPU Architecture:Any

[29 Jun 2005 8:32] Vadim Tkachenko
Description:
I've create InnoDB table

CREATE TABLE t1 (id int auto_increment primary key) ENGINE=InnoDB;

when I try SHOW TABLE STATUS and then exit; I got:

InnoDB: Assertion failure in thread 1115700144 in file trx0trx.c line 286
InnoDB: Failing assertion: trx->conc_state == TRX_NOT_STARTED
InnoDB: We intentionally generate a memory trap.

bt:
#0  0x08359676 in trx_free (trx=0x40264868) at mem0mem.ic:467
#1  0x083599e8 in trx_free_for_mysql (trx=0x40264868) at trx0trx.c:342
#2  0x082583ec in innobase_close_connection (thd=0x188) at ha_innodb.cc:2121
#3  0x0824bc93 in ha_close_connection (thd=0x8c791d0) at handler.cc:514
#4  0x08164db0 in ~THD (this=0x8c791d0) at sql_class.cc:405
#5  0x08176743 in end_thread (thd=0x8c791d0, put_in_cache=true) at mysqld.cc:1503
#6  0x0819e7ec in handle_one_connection (arg=0x0) at sql_parse.cc:1150
#7  0x40046aa7 in start_thread () from /lib/tls/libpthread.so.0
#8  0x40177c2e in clone () from /lib/tls/libc.so.6

I did not see it in 5.0.7

How to repeat:
mysql client:

create database test1;
CREATE TABLE t1 (id int auto_increment primary key) ENGINE=InnoDB;
exit;

mysql test1
show table status;
exit;

-> mysqld crashes.
[29 Jun 2005 14:02] Marko Mäkelä
It appears to happen with a simpler table definition as well.
[29 Jun 2005 14:58] Marko Mäkelä
The SHOW TABLE STATUS implicitly starts a transaction (and locks the table) by invoking ha_innobase::get_auto_increment(). However, the statement does not autocommit or release the lock. This is an error in the MySQL layer; the InnoDB assertion merely catches the error. I'm changing the category of this bug and unassigning myself from it.
[29 Jun 2005 18:50] 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/internals/26536
[29 Jun 2005 18:52] Heikki Tuuri
Hi!

The reason why this bug does not happen in 4.1 is that MySQL does call ::external_lock() there:

Breakpoint 2, ha_innobase::external_lock(THD*, int) (this=0x8b3c9e8,
    thd=0x8b3cf20, lock_type=0) at ha_innodb.cc:5054
5054            row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
(gdb) bt
#0  ha_innobase::external_lock(THD*, int) (this=0x8b3c9e8, thd=0x8b3cf20,
    lock_type=0) at ha_innodb.cc:5054
#1  0x081382a9 in lock_external (thd=0x8b3cf20, tables=0x49620430, count=1)
    at lock.cc:201
#2  0x081380a6 in mysql_lock_tables(THD*, st_table**, unsigned, unsigned) (
    thd=0x8b3cf20, tables=0x49620430, count=1, flags=0) at lock.cc:134
#3  0x08176458 in open_ltable(THD*, st_table_list*, thr_lock_type) (
    thd=0x8b3cf20, table_list=0x4962040c, lock_type=TL_READ)
    at sql_base.cc:1657
#4  0x081f1151 in mysqld_extend_show_tables(THD*, char const*, char const*) (
    thd=0x8b3cf20, db=0x8b1eaf8 "test",
    wild=0x8b3c9e8 "(r;\b@\v´\b\210˳\b\220˳\b") at sql_show.cc:520
#5  0x08155bc7 in mysql_execute_command(THD*) (thd=0x8b3cf20)
    at sql_string.h:87
#6  0x081588a0 in mysql_parse(THD*, char*, unsigned) (thd=0x8b3cf20,
    inBuf=0x8b3a7f8 "show table status", length=146001756) at sql_parse.cc:4243
#7  0x0815191d in dispatch_command(enum_server_command, THD*, char*, unsigned)
    (command=COM_QUERY, thd=0x8b3cf20, packet=0x8b367c1 "", packet_length=18)
    at sql_parse.cc:1502
#8  0x08151226 in do_command(THD*) (thd=0x8b3cf20) at sql_parse.cc:1315
#9  0x08150681 in handle_one_connection (arg=0x8b3c9e8) at sql_parse.cc:1047
#10 0x40062f60 in pthread_start_thread () from /lib/i686/libpthread.so.0
#11 0x400630fe in pthread_start_thread_event () from /lib/i686/libpthread.so.0
#12 0x401f5327 in clone () from /lib/i686/libc.so.6
(gdb)

In 5.0, MySQL does NOT call ::external_lock(). Even if InnoDB would register the transaction, MySQL does not commit it.

I have now committed a patch that fixes this particular crash. I have updated the synopsis of this bug report, since a simultaneus DROP TABLE might crash mysqld. Someone has to study this.

Regards,

Heikki
[25 Jul 2005 8:58] Sergei Glukhov
I tried to find the situation when 'drop table' leads to crash, but
can't get a crash. Heikki, could you give me an test example or an idea how
it can be checked?
[29 Jul 2005 8:24] Sergei Glukhov
Checked on latest 5.0 tree, can't repeat