Bug #27296 Assertion in ALTER TABLE SET DEFAULT in Linux Debug build (possible deadlock)
Submitted: 20 Mar 2007 16:19 Modified: 15 Jul 2007 9:35
Reporter: Aleksey Karyakin Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Server: Locking Severity:S3 (Non-critical)
Version:5.0.37/5.0BK OS:Linux (Linux)
Assigned to: Konstantin Osipov CPU Architecture:Any

[20 Mar 2007 16:19] Aleksey Karyakin
Description:
ALTER TABLE SET DEFAULT command crashes server if compiled in debug mode, on Linux. The crash occurs in the following assertion: 

bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, bool is_not_commit)
{
......... skipped ......
/*
Assert that we do not own LOCK_open. If we would own it, other
threads could not close their tables. This would make a pretty
deadlock.
*/
safe_mutex_assert_not_owner(&LOCK_open);

LOCK_open mutex is held during all ALTER TABLE operation but the assertion it isn't. The Windows version also was debugged and the same problem appears there but assertion was not enable there. 

The server does not crash in non-Debug or Windows builds, if the logic behind the assertion is valid, there still would be the problem with potential deadlock.

The stack trace:

#0  0x00e00402 in __kernel_vsyscall ()
#1  0x00c94fb7 in pthread_kill () from /lib/libpthread.so.0
#2  0x0835c769 in write_core (sig=6) at stacktrace.c:245
#3  0x081eae4d in handle_segfault (sig=6) at mysqld.cc:2128
#4  <signal handler called>
#5  0x00e00402 in __kernel_vsyscall ()
#6  0x00b45d40 in raise () from /lib/libc.so.6
#7  0x00b47591 in abort () from /lib/libc.so.6
#8  0x00b3f38b in __assert_fail () from /lib/libc.so.6
#9  0x081e1756 in wait_if_global_read_lock (thd=0x9c8e598, abort_on_refresh=false, is_not_commit=false) at lock.cc:1218
#10 0x082d776d in ha_commit_trans (thd=0x9c8e598, all=false) at handler.cc:722
#11 0x0831545a in mysql_alter_table (thd=0x9c8e598, new_db=0x9cc6768 "test", new_name=0x9cc65a0 "t", create_info=0x9c8eb98, table_list=0x9cc65c8, fields=@0x9c8eabc, keys=@0x9c8eab0, order_num=0, order=0x0, ignore=false, alter_info=0x9c8ecec, do_send_ok=true) at sql_table.cc:3751
#12 0x08204c0a in mysql_execute_command (thd=0x9c8e598) at sql_parse.cc:3140
#13 0x0820b80a in mysql_parse (thd=0x9c8e598, inBuf=0x9cc6540 "alter table t alter a set default 1", length=35) at sql_parse.cc:5831
#14 0x0820e1a4 in dispatch_command (command=COM_QUERY, thd=0x9c8e598, packet=0x9cbe4e1 "alter table t alter a set default 1", packet_length=36) at sql_parse.cc:1777
#15 0x0820f741 in do_command (thd=0x9c8e598) at sql_parse.cc:1561
#16 0x08210701 in handle_one_connection (arg=0x9c8e598) at sql_parse.cc:1192
#17 0x00c903db in start_thread () from /lib/libpthread.so.0
#18 0x00bea26e in clone () from /lib/libc.so.6

(line numbers may be incorrect since modified binary was used, however, the problem has been verified to exist in freshly built 3.0.37 community server).

The problem was checked with InnoDB and SolidDB table types.

How to repeat:
The following script crashes server:

DROP TABLE IF EXISTS T;
CREATE TABLE T (A INT) engine=innodb;
ALTER TABLE T ALTER A SET DEFAULT 1;

Linux version is RedHat Fedora Core 6:

Linux saturn 2.6.20-1.2925.fc6 #1 SMP Sat Mar 10 18:20:58 EST 2007 i686 i686 i386 GNU/Linux
[20 Mar 2007 16:46] MySQL Verification Team
Thank you for the bug report. MyISAM engine isn't affected as 4.1 and 5.1
server version as well:

[miguel@light 5.0]$ bin/mysql -uroot test
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.40-debug Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> DROP TABLE IF EXISTS T;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> CREATE TABLE T (A INT) engine=innodb;
Query OK, 0 rows affected (0.06 sec)

mysql> ALTER TABLE T ALTER A SET DEFAULT 1;
ERROR 2013 (HY000): Lost connection to MySQL server during query

[New Thread -1264501872 (LWP 6322)]
070320 13:37:06 [Note] /home/miguel/dbs/5.0/libexec/mysqld: ready for connections.
Version: '5.0.40-debug'  socket: '/tmp/mysql.sock'  port: 3306  Source distribution
[New Thread -1264702576 (LWP 6341)]
mysqld: lock.cc:1217: bool wait_if_global_read_lock(THD*, bool, bool): Assertion `! (&LOCK_open)->count || ! pthread_equal(pthread_self(), (&LOCK_open)->thread)' failed.

Program received signal SIGABRT, Aborted.
[Switching to Thread -1264702576 (LWP 6341)]
0x009e2402 in __kernel_vsyscall ()
(gdb) bt full
#0  0x009e2402 in __kernel_vsyscall ()
No symbol table info available.
#1  0x00138d40 in raise () from /lib/libc.so.6
No symbol table info available.
#2  0x0013a591 in abort () from /lib/libc.so.6
No symbol table info available.
#3  0x0013238b in __assert_fail () from /lib/libc.so.6
No symbol table info available.
#4  0x082136f8 in wait_if_global_read_lock (thd=0xa4fcaa0, abort_on_refresh=false, is_not_commit=false) at lock.cc:1217
        old_message = 0x0
        result = false
        need_exit_cond = false
        _db_func_ = 0xe <Address 0xe out of bounds>
        _db_file_ = 0xa4fd498 ""
        _db_level_ = 142731540
        _db_framep_ = (char **) 0x4
        __PRETTY_FUNCTION__ = "bool wait_if_global_read_lock(THD*, bool, bool)"
#5  0x0830e20d in ha_commit_trans (thd=0xa4fcaa0, all=false) at handler.cc:686
<CUT>

[miguel@light 5.0]$ bin/mysql -uroot test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.40-debug Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> DROP TABLE IF EXISTS T;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE T (A INT) engine=MyISAM;
Query OK, 0 rows affected (0.00 sec)

mysql> ALTER TABLE T ALTER A SET DEFAULT 1;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> select version();
+--------------+
| version()    |
+--------------+
| 5.0.40-debug | 
+--------------+
1 row in set (0.00 sec)

mysql>
[20 Mar 2007 17:16] Heikki Tuuri
This is a MySQL Server bug, not an InnoDB bug.
[15 Jul 2007 9:34] 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/30939

ChangeSet@1.2521, 2007-07-15 13:34:35+04:00, kostja@bodhi.(none) +2 -0
  Add a teste case for Bug#27296 "Assertion in ALTER TABLE SET DEFAULT in 
  Linux Debug build (possible deadlock)"
  
  The bug is not repeatable any more.
[15 Jul 2007 9:35] Konstantin Osipov
The bug is not repeatable any more. Adding the test case to the test suite.
[17 Jul 2007 15:30] Bugs System
Pushed into 5.0.48
[17 Jul 2007 15:31] Bugs System
Pushed into 5.1.21-beta