Bug #8677 Crash accessing InnoDB type temp table, MyISAM table locked with LOCK TABLES
Submitted: 22 Feb 2005 11:17 Modified: 6 Apr 2005 14:07
Reporter: Dmitry Kochin Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S2 (Serious)
Version:4.1.10 OS:Windows (Windows XP)
Assigned to: Heikki Tuuri CPU Architecture:Any

[22 Feb 2005 11:17] Dmitry Kochin
Description:
The server crashes when executing query with locking commands

How to repeat:
Create a table in the empty database:

CREATE TABLE `x` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(100) NOT NULL default '',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251; 

INSERT INTO `x` (`name`) VALUES ('xyz'), ('abcd');

And then execute the following statements:

drop table if exists xx;

LOCK TABLES x WRITE;

CREATE TEMPORARY TABLE xx
SELECT id
FROM x
WHERE id=6
LIMIT 2;

UPDATE xx
INNER JOIN x ON xx.id=x.id
SET x.name='aa';

UNLOCK TABLES;

The server crashes.
I executed these statements using MySQL Control Center, although I don't think this is relevant.
[22 Feb 2005 12:21] Aleksey Kishkin
I am not able to reproduce it. Could you please check these commands with mysql.exe (mysql console)? If you have other ideas how to reproduce it please let us know..

E:\mysql4.1.10\bin>mysql.exe -u root test
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3 to server version: 4.1.10

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

mysql> CREATE TABLE `x` (
    ->   `id` int(11) NOT NULL auto_increment,
    ->   `name` varchar(100) NOT NULL default '',
    ->   PRIMARY KEY  (`id`)
    -> ) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
Query OK, 0 rows affected (0.03 sec)

mysql>
mysql> INSERT INTO `x` (`name`) VALUES ('xyz'), ('abcd');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql>

mysql> drop table if exists xx;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql>
mysql> LOCK TABLES x WRITE;
Query OK, 0 rows affected (0.00 sec)

mysql>
mysql> CREATE TEMPORARY TABLE xx
    -> SELECT id
    -> FROM x
    -> WHERE id=6
    -> LIMIT 2;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql>
mysql> UPDATE xx
    -> INNER JOIN x ON xx.id=x.id
    -> SET x.name='aa';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0

mysql>
mysql> UNLOCK TABLES;
Query OK, 0 rows affected (0.00 sec)

mysql>
[22 Feb 2005 13:55] Dmitry Kochin
Yes, the bug is reproducible in the console.
The process crashing is mysqld-nt.exe.

If you need any dumps that are generated by windows XP, just ask me. I don't know how to attach a file to the bug report.

E:\MySQL\bin>mysql.exe --force --verbose --user=root --password=xxxxxxx < crash.sql
--------------
CREATE TABLE `x` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(100) NOT NULL default '',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251
--------------

ERROR 1050 (42S01) at line 3: Table 'x' already exists
--------------
INSERT INTO `x` (`name`) VALUES ('xyz'), ('abcd')
--------------

--------------
drop table if exists xx
--------------

--------------
LOCK TABLES x WRITE
--------------

--------------
CREATE TEMPORARY TABLE xx
SELECT id
FROM x
WHERE id=6
LIMIT 2
--------------

--------------
UPDATE xx
INNER JOIN x ON xx.id=x.id
SET x.name='aa'
--------------

ERROR 2013 (HY000) at line 21: Lost connection to MySQL server during query
--------------
UNLOCK TABLES
--------------

ERROR 2006 (HY000) at line 25: MySQL server has gone away
[22 Feb 2005 14:29] MySQL Verification Team
I wasn't able to repeat too. Can you provide your my.ini file ?

Thanks in advance.
[22 Feb 2005 15:13] Dmitry Kochin
I have attached my ini file. I also have dumps created by windows XP, but they are 900kb compressed, so I can not attach them too.
[22 Feb 2005 15:38] MySQL Verification Team
I was able to repeat the crash using your my.ini file. I will try
the call stack. Thank you for the bug report.
[22 Feb 2005 16:00] Dmitry Kochin
No problem :)
MySql is the best and I will do my best to make it better :)
[22 Feb 2005 16:01] MySQL Verification Team
Notice that even the table is MyISAM the crash happens in InnoDB code
at:

/row0sel.c
--2915--
	if (trx->n_mysql_tables_in_use == 0) {
		fputs(
"InnoDB: Error: MySQL is trying to perform a SELECT\n"
"InnoDB: but it has not locked any tables in ::external_lock()!\n",
                      stderr);
		trx_print(stderr, trx);
                fputc('\n', stderr);
		ut_a(0);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^LINE OF CRASH
	}

when executing:

mysql> UPDATE xx
    -> INNER JOIN x ON xx.id=x.id
    -> SET x.name='aa';

Below call stack:

mysqld-debug.exe!row_search_for_mysql(unsigned char * buf=0x03897658, unsigned long mode=1, row_prebuilt_struct * prebuilt=0x02458ea0, unsigned long match_mode=0, unsigned long direction=0)  Line 2922 + 0x78	C
mysqld-debug.exe!ha_innobase::index_read(unsigned char * buf=0x03897658, const unsigned char * key_ptr=0x00000000, unsigned int key_len=0, ha_rkey_function find_flag=HA_READ_AFTER_KEY)  Line 3055 + 0x17	C++
mysqld-debug.exe!ha_innobase::index_first(unsigned char * buf=0x03897658)  Line 3294 + 0x15	C++
mysqld-debug.exe!ha_innobase::rnd_next(unsigned char * buf=0x03897658)  Line 3386 + 0xf	C++
mysqld-debug.exe!rr_sequential(st_read_record * info=0x0388b7fc)  Line 188 + 0x1b	C++
mysqld-debug.exe!join_init_read_record(st_join_table * tab=0x0388b7d8)  Line 6221 + 0xd	C++
mysqld-debug.exe!sub_select(JOIN * join=0x0388a850, st_join_table * join_tab=0x0388b7d8, int end_of_records=0)  Line 5785 + 0xa	C++
mysqld-debug.exe!do_select(JOIN * join=0x0388a850, List<Item> * fields=0x041bf214, st_table * table=0x00000000, Procedure * procedure=0x00000000)  Line 5693 + 0xf	C++
mysqld-debug.exe!JOIN::exec()  Line 1480 + 0x36	C++
mysqld-debug.exe!mysql_select(THD * thd=0x03882328, Item * * * rref_pointer_array=0x03882560, st_table_list * tables=0x0388a458, unsigned int wild_num=0, List<Item> & fields={...}, Item * conds=0x00000000, unsigned int og_num=0, st_order * order=0x00000000, st_order * group=0x00000000, Item * having=0x00000000, st_order * proc_param=0x00000000, unsigned long select_options=268435584, select_result * result=0x0388a7e8, st_select_lex_unit * unit=0x03882374, st_select_lex * select_lex=0x03882474)  Line 1602	C++
mysqld-debug.exe!mysql_multi_update(THD * thd=0x03882328, st_table_list * table_list=0x0388a458, List<Item> * fields=0x038824e0, List<Item> * values=0x03882678, Item * conds=0x00000000, unsigned long options=0, enum_duplicates handle_duplicates=DUP_ERROR, int ignore=0, st_select_lex_unit * unit=0x03882374, st_select_lex * select_lex=0x03882474)  Line 697 + 0x52	C++
mysqld-debug.exe!mysql_execute_command(THD * thd=0x03882328)  Line 2737 + 0x47	C++
mysqld-debug.exe!mysql_parse(THD * thd=0x03882328, char * inBuf=0x0388a3d0, unsigned int length=52)  Line 4142 + 0x9	C++
mysqld-debug.exe!dispatch_command(enum_server_command command=COM_QUERY, THD * thd=0x03882328, char * packet=0x03886369, unsigned int packet_length=53)  Line 1479 + 0x1d	C++
mysqld-debug.exe!do_command(THD * thd=0x03882328)  Line 1292 + 0x31	C++
mysqld-debug.exe!handle_one_connection(void * arg=0x03882328)  Line 1024 + 0x9	C++
mysqld-debug.exe!pthread_start(void * param=0x0388e360)  Line 63 + 0x7	C
mysqld-debug.exe!_threadstart(void * ptd=0x00e6ef78)  Line 173 + 0xd	C
kernel32.dll!7c80b50b() 	
kernel32.dll!7c8399f3()
[22 Feb 2005 16:51] Heikki Tuuri
Hi!

I guess that the TEMPORARY table is InnoDB type.

I will check how I can the the value of n_mysql_tables_in_use right in this multi-table update.

Regards,

Heikki
[22 Feb 2005 20:00] Heikki Tuuri
Fixed in 4.1.11.

Thank you,

Heikki