Bug #50366 | InnoDB Assertion failure when converting from MyISAM to InnoDB | ||
---|---|---|---|
Submitted: | 15 Jan 2010 14:09 | Modified: | 2 Oct 2013 17:30 |
Reporter: | Edward Dore | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S1 (Critical) |
Version: | 5.0.90, 5.1.43 | OS: | Any (CentOS 5.4 x86-64, XP) |
Assigned to: | Assigned Account | CPU Architecture: | Any |
[15 Jan 2010 14:09]
Edward Dore
[15 Jan 2010 14:30]
Valeriy Kravchuk
Please, check if this is repeatable with a newer version, 5.0.89. If it is, please, send your my.cnf file content.
[31 Jan 2010 20:41]
Edward Dore
Apologies for the delay in replying. I have now tested this with the MySQL 5.0.90 community edition RPM in our lab and am encountering exactly the same behavior when trying to convert the storage engine this table from MyISAM to InnoDB. I installed CentOS 5.4 x86-64 on a Dell PowerEdge R200 server in our lab and then installed the MySQL-server-community-5.0.90-0.rhel5 RPM downloaded from one of the MySQL.com mirrors in the UK before loading an exact copy of the database from the live server taken as a backup via mysqldump on January 15th when we first experienced this problem (this is the same mysqldump as I tried to import with ENGINE=InnoDB; on the "users" table in question. The only change to the default /etc/my.cnf was to specify the log-error location. Once the "ALTER TABLE `users` ENGINE=InnoDB;" command is run from the CLI client, the conversion begins and then after a minute or two the server crashes. Some of the conversion is evidently completed fine as the /var/lib/mysql/ibdata1 file grows to 243MB and the server doesn't crash straight away. When the server crashes, it looks like it reboots and tries to recover the transaction only to then crash again and get itself into a reboot loop. I've included the contents of the log-error file for the first couple of times round this loop. [root@localhost ~]# rpm -q MySQL-server-community MySQL-server-community-5.0.90-0.rhel5 [root@localhost ~]# cat /etc/redhat-release CentOS release 5.4 (Final) [root@localhost ~]# cat /etc/my.cnf [mysqld] #datadir=/var/lib/mysql #socket=/var/lib/mysql/mysql.sock #user=mysql # Default to using old password format for compatibility with mysql 3.x # clients (those using the mysqlclient10 compatibility package). #old_passwords=1 [mysqld_safe] log-error=/var/log/mysqld.log #pid-file=/var/run/mysqld/mysqld.pid
[31 Jan 2010 20:43]
Edward Dore
Contents of the log-error files from InnoDB assertion failure. Clipped to the first couple of MySQL restarts/recovery attempts
Attachment: log-error crash.txt (text/plain), 11.44 KiB.
[31 Jan 2010 22:10]
MySQL Verification Team
I can repeat this crash using alot of fake data in the supplied table. Version: '5.0.90-community-nt' socket: '' port: 3306 MySQL Community Edition (GPL) 100201 0:09:33InnoDB: Assertion failure in thread 10960 in file .\log\log0log.c line 202 InnoDB: Failing assertion: len < log->buf_size / 2 InnoDB: We intentionally generate a memory trap. <cut> mysqld-nt.exe!log_reserve_and_open()[log0log.c:202] mysqld-nt.exe!mtr_log_reserve_and_write()[mtr0mtr.c:147] mysqld-nt.exe!mtr_commit()[mtr0mtr.c:190] mysqld-nt.exe!row_ins_index_entry_low()[row0ins.c:2108] mysqld-nt.exe!row_ins_index_entry()[row0ins.c:2177] mysqld-nt.exe!row_ins_index_entry_step()[row0ins.c:2246] mysqld-nt.exe!row_ins()[row0ins.c:2380] mysqld-nt.exe!row_ins_step()[row0ins.c:2487] mysqld-nt.exe!row_insert_for_mysql()[row0mysql.c:1157] mysqld-nt.exe!ha_innobase::write_row()[ha_innodb.cc:3304] mysqld-nt.exe!copy_data_between_tables()[sql_table.cc:4244] mysqld-nt.exe!mysql_alter_table()[sql_table.cc:3840] mysqld-nt.exe!mysql_execute_command()[sql_parse.cc:3571] mysqld-nt.exe!mysql_parse()[sql_parse.cc:6449] mysqld-nt.exe!dispatch_command()[sql_parse.cc:1961] mysqld-nt.exe!handle_one_connection()[sql_parse.cc:1233] mysqld-nt.exe!pthread_start()[my_winthread.c:85] mysqld-nt.exe!_callthreadstart()[thread.c:295] mysqld-nt.exe!_threadstart()[thread.c:275] kernel32.dll!BaseThreadStart() The table had 400000 rows in it before being converted. I'll upload a private testcase soon.
[31 Jan 2010 22:14]
Edward Dore
The table I was using had 38509 rows in it, so you're in the same region :) I've just managed to get it to convert by ramping up innodb_buffer_pool_size, although I haven't tested what size it needs to be - I just set it to 4GB as the test server has 8GB of RAM.
[1 Feb 2010 6:34]
Valeriy Kravchuk
Crash is repeatable with recent test case from Shane uploaded in private, both with -debug and non-debug binaries.
[1 Feb 2010 19:12]
Marko Mäkelä
Here is some background information that may be relevant for this bug. All operations that are covered by the InnoDB redo log are grouped into mini-transactions (mtr). Usually, a mtr should latch only a few pages. For example, operations on off-page columns (BLOBs) will keep at most two BLOB pages latched at a time. The biggest mini-transactions occur during a B-tree split. In the worst case, splitting a B-tree leaf node will be propagated all the way to the root node. Again, in the worst case, when index records are long, each b-tree node will contain few node pointers, and the page-splitting mini-transaction may end up latching up to half the pages in the index tree. During crash recovery, all pages touched by the mini-transaction will have to be latched in the buffer pool at the same time. Thus, if InnoDB crashes due to running out of buffer pool in a mini-transaction, the redo log application during crash recovery will likely crash as well, unless the buffer pool size is enlarged.
[1 Feb 2010 19:24]
Marko Mäkelä
Sorry, my previous comment is a little misleading. If InnoDB runs out of buffer pool during the execution of a mini-transaction, mtr_commit(mtr) will not be executed and no redo log will be written for the mtr. Thus, crash recovery would not see the oversized mtr. If there is something oversized that kills InnoDB at crash recovery, that should be in the rollback of incomplete transactions.
[30 Apr 2012 12:37]
MySQL Verification Team
bug #42170 is a duplicate of this.
[2 Oct 2013 17:30]
Bugs System
Noted in 5.5.35, 5.6.15, 5.7.3 changelogs: "Converting a table with a large number of columns from "MyISAM" to "InnoDB" would cause an assertion due to insufficient log buffer space. Instead of asserting, "InnoDB" now attempts to increase log buffer size automatically if the redo log size is too large." Thank you for the bug report.
[4 Dec 2013 9:24]
Laurynas Biveinis
5.5$ bzr log -r 4489 ------------------------------------------------------------ revno: 4489 committer: Yasufumi Kinoshita <yasufumi.kinoshita@oracle.com> branch nick: mysql-5.5 timestamp: Mon 2013-09-30 13:41:48 +0900 message: Bug#11758196 : INNODB ASSERTION FAILURE WHEN CONVERTING FROM MYISAM TO INNODB Changed to try to extend log buffer instead of crash, when log size is too large for the size. Approved by Marko in rb#3229
[4 Dec 2013 9:25]
Laurynas Biveinis
5.5$ bzr log -r 4490 ------------------------------------------------------------ revno: 4490 committer: Yasufumi Kinoshita <yasufumi.kinoshita@oracle.com> branch nick: mysql-5.5 timestamp: Mon 2013-09-30 15:02:54 +0900 message: Adjustment for fix for Bug#11758196 log_buffer_extend() should fill the new buffer with 0.