Bug #27577 | ALTER TABLE .. TYPE=InnoDB causes uninterruptable hang | ||
---|---|---|---|
Submitted: | 2 Apr 2007 1:13 | Modified: | 22 May 2007 16:05 |
Reporter: | Chris Elsworth | Email Updates: | |
Status: | Can't repeat | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S2 (Serious) |
Version: | 5.1.16-beta | OS: | Linux (Linux 2.6.17 x86_64 (Ubuntu)) |
Assigned to: | Inaam Rana | CPU Architecture: | Any |
[2 Apr 2007 1:13]
Chris Elsworth
[2 Apr 2007 6:25]
Heikki Tuuri
Chris, what do SHOW INNODB STATUS\G and SHOW PROCESSLIST print during the hang? How long does it take to hang? Regards, Heikki
[2 Apr 2007 10:47]
Chris Elsworth
Heikki, SHOW PROCESSLIST / SHOW INNODB STATUS do not respond after the hang; the entire server seems to go into some kind of deadlock. It doesn't accept any new connections, and any existing connections that were open, don't return to any commands. After executing the ALTER TABLE it varies on time to deadlock but is between 2 and 15 minutes. For comparison, the "null-op" ALTER TABLE FileGroup TYPE=MyISAM I did as a test took 6 minutes. Did you manage to recreate the hang?
[2 Apr 2007 23:42]
Chris Elsworth
Heikki, After some more experimentation, it appears as though the order of the rows in the MyISAM table I tarred up may have some bearing. This works: ALTER TABLE FileGroup ORDER BY FileID; ALTER TABLE FileGroup TYPE=InnoDB; That is, ordering the rows by FileID before converting makes the conversion work. I have repeated this several times with 100% success. I have not yet tried ordering by other columns.
[3 Apr 2007 8:53]
Heikki Tuuri
Chris, I will try to repeat this. I assume that after the hang, InnoDB did not start within 10 minutes to print diagnostics to the .err log? If the hang happens on an InnoDB semaphore, that is what normally happens. Regards, Heikki
[3 Apr 2007 13:04]
Chris Elsworth
Heikki, I haven't seen any information dumped to the error log yet. I've just done it again and realised that only SHOW INNODB STATUS does not return; I can still do SHOW FULL PROCESSLIST etc: Id: 1 User: root Host: localhost db: test Command: Query Time: 2997 State: copy to tmp table Info: alter table FileGroup type=innodb As you can see this one has been hung nearly an hour. Apologies for the earlier misinformation that the entire server seemed to deadlock, that was wrong. Only the ALTER TABLE and SHOW INNODB STATUS seem to be hanging for me with this test.
[3 Apr 2007 13:17]
Chris Elsworth
Heikki, Just one more bit of evidence to add to this; after the first conversion hangs, if I then try to start another one on an unrelated table, even in an unrelated database, in the same server, that hangs too, in state 'creating table'.
[4 Apr 2007 15:38]
Heikki Tuuri
Since there is no output in the .err log, it is probably hanging on some MySQL mutex. I hope I have time to test this. Could it be this critical binlog hang bug that is fixed in 5.1.17: http://bugs.mysql.com/bug.php?id=26079 ? Regards, Heikki
[5 Apr 2007 17:11]
Chris Elsworth
Heikki, I don't think so - binary logging is disabled on this host. It is a replication slave so does relay logging, but for the purposes of this test I disabled replication with skip-slave-start (see config above). So there should be nothing written to any form of binary log.
[4 May 2007 14:08]
Heikki Tuuri
Assigning this mystical hang to Inaam. Please compile MySQL with: ./BUILD/compile-pentium64-debug-max and try to repeat this inside gdb so that we get the stack trace from the hang place. --Heikki
[10 May 2007 12:27]
Heikki Tuuri
Chris, Inaam is not able to repeat the hang. I guess the only way to find the bug is that you compile mysqld with: CFLAGS="-g" CXXFLAGS="-g" ./configure ... and run inside gdb. When it hangs, kill -11 the mysqld process, so that gdb breaks execution. Then look at all threads and their stack traces. Regards, Heikki
[14 May 2007 2:29]
Thomas Hurst
This seems to be Linux-specific; we've been unable to reproduce the problem on 2 different FreeBSD systems. We've been unable to get much of use out of gdb so far; it hangs enumerating threads inside wait4(), and killing MySQL just results in a zombie. I wonder if we need a kernel debugger or so...
[14 May 2007 11:50]
Heikki Tuuri
Thomas, you do not need a kernel debugger. mysqld is a perfectly normal user process. I have not seen such gdb hangs on 2.6.18-4-amd64 #1 SMP Mon Mar 26 11:36:53 CEST 2007 x86_64 GNU/Linux. When I have a hung mysqld process, I attach witg gdb to it. Then I send kill -11 to the mysqld process. Then execution breaks inside gdb, and I can query the threads and print their stack traces. Regards, Heikki
[14 May 2007 13:04]
Chris Elsworth
That's the problem Heikki, mysqld does not stop execution and hand control to gdb. We get this: root@db9:~# ps auxw | grep mysqld root 8425 0.0 0.0 2772 568 pts/0 S 13:40 0:00 /bin/sh /usr/local/mysql/bin/mysqld_safe mysql 8462 52.3 33.2 1120612 683456 pts/0 Sl 13:40 10:16 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/db/mysql --user=mysql --pid-file=/db/mysql/mysqld.pid --skip-external-locking --port=3306 --socket=/tmp/mysql.sock root 8600 0.0 0.0 3908 808 pts/1 S+ 13:59 0:00 grep mysqld root@db9:~# gdb /usr/local/mysql/bin/mysqld 8462 GNU gdb 6.4.90-debian Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "x86_64-linux-gnu"...(no debugging symbols found) Using host libthread_db library "/lib/libthread_db.so.1". Attaching to program: /usr/local/mysql-5.0.37-linux-x86_64-glibc23/bin/mysqld, process 8462 Reading symbols from /lib/librt.so.1...(no debugging symbols found)...done. Loaded symbols for /lib/librt.so.1 Reading symbols from /lib/libdl.so.2...(no debugging symbols found)...done. Loaded symbols for /lib/libdl.so.2 Reading symbols from /lib/libpthread.so.0... (no debugging symbols found)...done. [Thread debugging using libthread_db enabled] [New Thread 47087960752640 (LWP 8462)] [New Thread 1133554000 (LWP 8481)] [New Thread 1133287760 (LWP 8476)] There is no further output. I then issue the kill: root@db9:~# kill -11 8462 gdb does absolutely nothing - no more output. I inspect the process again: root@db9:~# ps auxw | grep mysqld root 8425 0.0 0.0 2772 568 pts/0 S 13:40 0:00 /bin/sh /usr/local/mysql/bin/mysqld_safe mysql 8462 45.8 0.0 0 0 pts/0 Zl 13:40 10:16 [mysqld] <defunct> root 8610 0.0 0.7 24092 14920 pts/1 S+ 14:00 0:00 gdb /usr/local/mysql/bin/mysqld 8462 root 8636 0.0 0.0 3908 812 pts/2 S+ 14:02 0:00 grep mysqld root@db9:~# mysqld appears to now be a zombie. So you see the problem we're having debugging this :) For this reason we now think we may be tickling a Linux kernel bug. Especially as we are unable to reproduce the hang in FreeBSD.
[22 May 2007 16:05]
Heikki Tuuri
Chris, thank you. I put this to the 'Can't repeat' status until someone is able to get gdb to work on this bug. Regards, Heikki
[22 May 2007 16:05]
Heikki Tuuri
Chris, thank you. I put this to the 'Can't repeat' status until someone is able to get gdb to work on this bug. Regards, Heikki
[8 Jun 2007 15:27]
Thomas Hurst
We've repeated this on FreeBSD 7-CURRENT, and managed to get a coredump using gcore. Very similar behavior to Linux; attaching gdb hangs in wait4(), MySQL won't die and still accepts connections, etc. gcore left the process in state STOP, looks like we'll need to reboot. Backtrace from the core: #0 0x000000080122cc9c in _umtx_op () from /lib/libc.so.7 #1 0x0000000800cb318b in pthread_cleanup_pop () from /lib/libthr.so.2 #2 0x0000000800cb1cda in pthread_cond_destroy () from /lib/libthr.so.2 #3 0x00000000004c1a75 in one_thread_per_connection_end () #4 0x00000000004ca6b0 in handle_one_connection () #5 0x0000000800cac124 in pthread_create () from /lib/libthr.so.2
[8 Jun 2007 15:47]
Thomas Hurst
This was with our own build of 5.1.19 and FreeBSD 7.0-CURRENT/AMD64 built on the 8th of June. The hang happened on shutdown after a "difficult repair" of another table, as described at http://dev.mysql.com/doc/refman/5.1/en/repair.html
[10 Jun 2007 21:26]
Thomas Hurst
Here's an excerpt from SHOW ENGINE INNODB MUTEX | InnoDB | buf0buf.c:545 | os_waits=0 | | InnoDB | buf0buf.c:547 | os_waits=0 | | InnoDB | buf0buf.c:545 | os_waits=0 | | InnoDB | buf0buf.c:547 | os_waits=0 | | InnoDB | buf0buf.c:545 | os_waits=0 | | InnoDB | buf0buf.c:547 | os_waits=0 | | InnoDB | buf0buf.c:545 | os_waits=0 | | InnoDB | buf0buf.c:597 | os_waits=0 | | InnoDB | fil0fil.c:1313 | os_waits=0 | | InnoDB | srv0start.c:1227 | os_waits=0 | | InnoDB | srv0start.c:1220 | os_waits=0 | | InnoDB | srv0start.c:1198 | os_waits=0 | | InnoDB | dict0mem.c:90 | os_waits=0 | | InnoDB | dict0mem.c:90 | os_waits=0 | | InnoDB | srv0srv.c:860 | os_waits=0 | | InnoDB | srv0srv.c:858 | os_waits=0 | | InnoDB | thr0loc.c:227 | os_waits=0 | | InnoDB | mem0pool.c:206 | os_waits=0 | | InnoDB | sync0sync.c:1302 | os_waits=0 | +--------+------------------+------------+ 1311116 rows in set (11.77 sec) The list bounces between buf0buf.c:545 and buf0buf.c:547 about 1311104 times. Here's SHOW INNODB STATUS: ===================================== 070610 22:25:39 INNODB MONITOR OUTPUT ===================================== Per second averages calculated from the last 3 seconds ---------- SEMAPHORES ---------- OS WAIT ARRAY INFO: reservation count 2359, signal count 2359 Mutex spin waits 0, rounds 0, OS waits 0 RW-shared spins 2921, OS waits 1025; RW-excl spins 6388, OS waits 1334 ------------ TRANSACTIONS ------------ Trx id counter 0 60951690 Purge done for trx's n:o < 0 60951670 undo n:o < 0 0 History list length 8 Total number of lock structs in row lock hash table 0 LIST OF TRANSACTIONS FOR EACH SESSION: ---TRANSACTION 0 0, not started, OS thread id 34381767264 MySQL thread id 26, query id 510990 admin0-mgt.newzbin.com 192.168.201.105 root show innodb status -------- FILE I/O -------- I/O thread 0 state: waiting for i/o request (insert buffer thread) I/O thread 1 state: waiting for i/o request (log thread) I/O thread 2 state: waiting for i/o request (read thread) I/O thread 3 state: waiting for i/o request (write thread) Pending normal aio reads: 0, aio writes: 0, ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0 Pending flushes (fsync) log: 0; buffer pool: 0 52541 OS file reads, 29073 OS file writes, 3814 OS fsyncs 0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s ------------------------------------- INSERT BUFFER AND ADAPTIVE HASH INDEX ------------------------------------- Ibuf: size 1, free list len 617, seg size 619, 38891 inserts, 38891 merged recs, 13668 merges Hash table size 21249871, used cells 1131661, node heap has 1717 buffer(s) 0.00 hash searches/s, 0.00 non-hash searches/s --- LOG --- Log sequence number 13 2404484002 Log flushed up to 13 2404484002 Last checkpoint at 13 2404484002 0 pending log writes, 0 pending chkp writes 1426 log i/o's done, 0.00 log i/o's/second ---------------------- BUFFER POOL AND MEMORY ---------------------- Total memory allocated 11488937550; in additional pool allocated 11610112 Dictionary memory allocated 496584 Buffer pool size 655360 Free buffers 592304 Database pages 61339 Modified db pages 0 Pending reads 0 Pending writes: LRU 0, flush list 0, single page 0 Pages read 57986, created 3393, written 51661 0.00 reads/s, 0.00 creates/s, 0.00 writes/s No buffer pool page gets since the last printout -------------- ROW OPERATIONS -------------- 0 queries inside InnoDB, 0 queries in queue 1 read views open inside InnoDB Main thread id 34381765792, state: waiting for server activity Number of rows inserted 89005, updated 794676, deleted 95871, read 3124944 0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s ---------------------------- END OF INNODB MONITOR OUTPUT ============================ And the thread states via top(1): 995 mysql 4 0 11637M 11642M sbwait 2 2:59 1.22% mysqld 995 mysql 96 0 11637M 11642M ucond 3 2:59 0.24% mysqld 995 mysql 96 0 11637M 11642M ucond 3 2:59 0.00% mysqld 995 mysql 96 0 11637M 11642M ucond 2 2:59 0.00% mysqld 995 mysql 96 0 11637M 11642M ucond 3 2:59 0.00% mysqld 995 mysql 96 0 11637M 11642M ucond 2 2:59 0.00% mysqld 995 mysql 96 0 11637M 11642M select 0 2:59 0.00% mysqld 995 mysql 96 0 11637M 11642M ucond 0 2:59 0.00% mysqld 995 mysql 96 0 11637M 11642M select 2 2:59 0.00% mysqld 995 mysql 96 0 11637M 11642M ucond 2 2:59 0.00% mysqld 995 mysql 96 0 11637M 11642M select 1 2:59 0.00% mysqld 995 mysql 20 0 11637M 11642M sigwai 3 2:59 0.00% mysqld 995 mysql 4 0 11637M 11642M sbwait 2 2:59 0.00% mysqld
[10 Jun 2007 21:55]
Thomas Hurst
After comparing with our slaves, this looks normal; we have a lot of InnoDB buffers, and thus a lot of buffer pool objects and their associated pair of mutexes, as per our InnoDB config: innodb_data_file_path = ibdata1:500M:autoextend innodb_buffer_pool_size = 10240M innodb_additional_mem_pool_size = 24M innodb_log_file_size = 256M innodb_log_buffer_size = 16M innodb_flush_log_at_trx_commit = 0 innodb_lock_wait_timeout = 50 innodb_flush_method = O_DIRECT innodb_file_per_table