Bug #12243 | MySQL Server crashes with 2 cursors (+ commit) | ||
---|---|---|---|
Submitted: | 28 Jul 2005 18:04 | Modified: | 10 Aug 2005 16:40 |
Reporter: | Andrey Hristov | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server | Severity: | S1 (Critical) |
Version: | 5.0.10-beta-200507260 | OS: | Linux (SLES9) |
Assigned to: | Konstantin Osipov | CPU Architecture: | Any |
[28 Jul 2005 18:04]
Andrey Hristov
[28 Jul 2005 18:06]
Andrey Hristov
bug12243
Attachment: bug12243.c (text/x-csrc), 5.43 KiB.
[28 Jul 2005 18:47]
Jorge del Conde
Hi Andrey, I was able to reproduce this bug using a recent 5.0 pull.
[28 Jul 2005 22:44]
Andrey Hristov
the table with the data
Attachment: dump.sql (application/octet-stream, text), 32.13 KiB.
[29 Jul 2005 7:51]
Andrey Hristov
Ultra simplified test case. Table definition in the source.
Attachment: bug12243_2.c (text/x-csrc), 1.20 KiB.
[29 Jul 2005 8:10]
Jan Lindström
Based on stack trace server crashes in row_search_for_mysql because no read view is assigned. This could be because MySQL does not call innobase_set_cursor_view() after commit in the next fetch on other cursor. I think this bug is in MySQL server code not inside of InnoDB code. Thus, every time MySQL does a operation on cursor it is needed first to set what cursor should be used. MySQL may not assume that InnoDB has correct read view for cursor assigned. Actually, after InnDB returns from row_search_for_mysql cursor read view is detached from the transaction to make sure that when row_search_for_mysql is called next time you must set cursor read view to correct cursor before you may fetch from it.
[29 Jul 2005 11:07]
Jan Lindström
Confirmed that this bug is because cursor view was not set before fetch. Bug is in MySQL server code. #0 0x0833e9ba in read_view_sees_trx_id (view=0x0, trx_id= {high = 0, low = 33025}) at read0read.ic:53 #1 0x0836167f in lock_clust_rec_cons_read_sees (rec=0x40df409b "", index=0x40add568, offsets=0x637a7b8c, view=0x0) at lock0lock.c:522 #2 0x08313c61 in row_search_for_mysql (buf=0x8c71880 "\001", mode=1, prebuilt=0x40ade668, match_mode=0, direction=1) at row0sel.c:3759 #3 0x0827301b in ha_innobase::general_fetch(char*, unsigned, unsigned) ( this=0x8c71758, buf=0x8c71880 "\001", direction=1, match_mode=0) at ha_innodb.cc:3970 #4 0x08273409 in ha_innobase::rnd_next(char*) (this=0x8c71758, buf=0x8c71880 "\001") at ha_innodb.cc:4161 #5 0x0825d148 in rr_sequential (info=0x8c6a1ac) at records.cc:193 #6 0x081f6a5f in sub_select (join=0x8c69128, join_tab=0x8c6a170, end_of_records=false) at sql_select.cc:9374 #7 0x081e5198 in Cursor::fetch(unsigned long) (this=0x8c6d3e0, num_rows=1) at sql_select.cc:1864 #8 0x0820f146 in mysql_stmt_fetch(THD*, char*, unsigned) (thd=0x8c362b0, packet=0x8c58ff9 "\002", packet_length=9) at sql_prepare.cc:2242 #9 0x081a5d8b in dispatch_command(enum_server_command, THD*, char*, unsigned) (command=COM_STMT_FETCH, thd=0x8c362b0, packet=0x8c58ff9 "\002", packet_length=9) at sql_parse.cc:1634 #10 0x081a56e3 in do_command(THD*) (thd=0x8c362b0) at sql_parse.cc:1467 #11 0x081a47fc in handle_one_connection (arg=0x8c362b0) at sql_parse.cc:1116
[6 Aug 2005 7:20]
Konstantin Osipov
I tracked the bug down. The bug is that InnoDB does not register it's handlerton in the list of statement handlertons when opening the second cursor. In sql_select.cc we have the following code to create a cursor read view: for (handlerton **pht= thd->transaction.stmt.ht; *pht; pht++) { const handlerton *ht= *pht; close_at_commit|= test(ht->flags & HTON_CLOSE_CURSORS_AT_COMMIT); if (ht->create_cursor_read_view) { info->ht= ht; info->read_view= (ht->create_cursor_read_view)(); ++info; } } So, to create a read view the storage engine handlerton must be registered in the list of handlertons used in the statement. But in ha_innobase::external_lock trans_register_ha is called only if trx->n_mysql_tables_in_use is zero: } else if (trx->n_mysql_tables_in_use == 0) { innobase_register_stmt(thd); } if we have an open active cursor within the transaction, this count is not reset, and is not null. So, InnoDB doesn't register the handlerton for subsequent cursors. I will try to write a patch shortly. Jan: please review.
[10 Aug 2005 14:56]
Konstantin Osipov
Subject: bk commit - 5.0 tree (konstantin:1.1975) BUG#11832 ChangeSet 1.1975 05/08/10 18:36:13 konstantin@mysql.com +5 -0 A fix and a test case for Bug#12243 "MySQL Server crashes with 2 cursors (+ commit)" and Bug#11832 "Server crash with InnoDB + Cursors" See comments to the changed files.
[10 Aug 2005 14:59]
Konstantin Osipov
Approved by Heikki Tuuri via email. http://lists.mysql.com/internals/28111
[10 Aug 2005 15:00]
Konstantin Osipov
Fixed in 5.0, currently tagged 5.0.12
[10 Aug 2005 16:40]
Jon Stephens
Thank you for your bug report. This issue has been committed to our source repository of that product and will be incorporated into the next release. If necessary, you can access the source repository and build the latest available version, including the bugfix, yourself. More information about accessing the source trees is available at http://www.mysql.com/doc/en/Installing_source_tree.html Additional info: Documented in 5.0.12 changelog.