Bug #1810 InnoDB rollback on delete from indexed table -> strange query results

Submitted: 11 Nov 2003 17:53 Modified: 13 Nov 2003 5:25
Reporter: [ name withheld ] Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S1 (Critical)
Version:4.0.11 OS:Linux (Linux Mandrake 9.1)
Assigned to: CPU Architecture:Any

[11 Nov 2003 17:53] [ name withheld ]
Description:
This report actually shows up a couple of issues, though the first may be a 
feature (I'm relatively new to MySQL). These operations are done on the 
indexed table as given in the "how to repeat" section of this report: 
 
1. selects on varchar columns where the contents are a number will succeed 
   if the select where clause value is a number and not a string, eg:: 
 
     select * from ids where id=1; 
 
   will work where the ids column is a varchar. As I say, this may be 
   intentional. 
2. When a delete operation is rolled back, a row may be accessed using the 
   above query, but not:: 
 
     select * from ids where id='1'; 
 
   ie. accessing the column using the correct data type. 
 

How to repeat:
Run the following:: 
 
    set autocommit=0; 
    CREATE TABLE ids (id varchar(255)) TYPE=InnoDB; 
    CREATE INDEX ids_id_idx on ids(id); 
    insert into ids values ('1'); 
    commit; 
    delete from ids where id='1'; 
    rollback; 
    select * from ids where id='1'; 
    select * from ids where id=1; 
    drop table ids; 
 
That will list an empty table on the first select, and the contents of the 
table on the second select. Note the id column is clearly a varchar. Now the 
fun part. Commenting out the "CREATE INDEX" statement makes BOTH selects work! 
 
It's a bug in the InnoDB implementation. Switching to BDB makes it work.
[12 Nov 2003 7:17] Heikki Tuuri
Hi!

I cannot repeat this with 4.0.17.

Are you using the query cache? What charset? What do EXPLAIN SELECT print?

Regards,

Heikki

mysql>
mysql>      set autocommit=0;
Query OK, 0 rows affected (0.00 sec)

mysql>     CREATE TABLE ids (id varchar(255)) TYPE=InnoDB;
Query OK, 0 rows affected (0.00 sec)

mysql>     CREATE INDEX ids_id_idx on ids(id);
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql>     insert into ids values ('1');
Query OK, 1 row affected (0.00 sec)

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

mysql>     delete from ids where id='1';
Query OK, 1 row affected (0.00 sec)

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

mysql>     select * from ids where id='1';
+------+
| id   |
+------+
| 1    |
+------+
1 row in set (0.00 sec)

mysql>     select * from ids where id=1;
+------+
| id   |
+------+
| 1    |
+------+
1 row in set (0.00 sec)

mysql>     explain select * from ids where id=1;
+-------+-------+---------------+------------+---------+------+------+----------
----------------+
| table | type  | possible_keys | key        | key_len | ref  | rows | Extra
                |
+-------+-------+---------------+------------+---------+------+------+----------
----------------+
| ids   | index | ids_id_idx    | ids_id_idx |     256 | NULL |    0 | Using whe
re; Using index |
+-------+-------+---------------+------------+---------+------+------+----------
----------------+
1 row in set (0.00 sec)

mysql>     explain select * from ids where id='1';
+-------+------+---------------+------------+---------+-------+------+----------
----------------+
| table | type | possible_keys | key        | key_len | ref   | rows | Extra
                |
+-------+------+---------------+------------+---------+-------+------+----------
----------------+
| ids   | ref  | ids_id_idx    | ids_id_idx |     256 | const |    1 | Using whe
re; Using index |
+-------+------+---------------+------------+---------+-------+------+----------
----------------+
1 row in set (0.00 sec)

mysql>
[12 Nov 2003 14:17] [ name withheld ]
I'm not sure I'm in a position to be able to upgrade to 4.0.17 unless someone 
releases Mandrake-9.1-compatible RPMs. 
 
I couldn't find how to check the charset. The EXPLAIN output follows: 
 
mysql> explain select * from ids where id=1;  
+-------+-------+---------------+------------+---------+------+------+--------------------------+  
| table | type  | possible_keys | key        | key_len | ref  | rows | Extra                     
|  
+-------+-------+---------------+------------+---------+------+------+--------------------------+  
| ids   | index | ids_id_idx    | ids_id_idx |     256 | NULL |    0 | Using  
where; Using index |  
+-------+-------+---------------+------------+---------+------+------+--------------------------+  
1 row in set (0.00 sec)  
  
mysql> explain select * from ids where id='1';  
+-------+-------+---------------+------+---------+------+------+-------+  
| table | type  | possible_keys | key  | key_len | ref  | rows | Extra |  
+-------+-------+---------------+------+---------+------+------+-------+  
| ids   | const | ids_id_idx    | NULL |    NULL | NULL |    1 |       |  
+-------+-------+---------------+------+---------+------+------+-------+  
1 row in set (0.00 sec)
[12 Nov 2003 14:25] [ name withheld ]
I have installed the 4.0.16 RPM from your download area, and that fixes the 
bug.
[13 Nov 2003 5:25] Heikki Tuuri
Hi!

I was able to repeat the bug with 4.0.8, and noticed that this bug was fixed in 4.0.12.

Best regards,

Heikki

MySQL/InnoDB-4.0.12, March 18, 2003 

Fixed a bug: MySQL could erroneously return 'Empty set' if InnoDB estimated an index range size to 0 records though the range was not empty; MySQL also failed to do the next-key locking in the case of an empty index range.

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.039 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.