Multi-table DELETE that uses innodb + index_merge/intersect may fail to delete rows

Bug #1006164 reported by Sergey Petrunia on 2012-05-29
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
MariaDB
Fix Released
High
Sergey Petrunia

Bug Description

Based on customer case, csc#250:

CREATE TABLE tbl (
   id PRIMARY KEY,
   key1 INT,
   key2 INT,
   KEY (key1),
   KEY (key2) ) engine=innodb;
...

DELETE tbl FROM tbl WHERE key1=const1 AND key2=const2;

^^ this will delete fewer rows than it actually matches.
* Problem happens only with InnoDB (not with MyISAM)
* Setting "index_merge=off" fixes the problem.
* Using a non-multi-table-table DELETE statement fixes the problem.

Sergey Petrunia (sergefp) wrote :

Doesn't occur in MariaDB 5.2, occurs in 5.3 and 5.5

Changed in maria:
assignee: nobody → Sergey Petrunia (sergefp)
importance: Undecided → High
status: New → In Progress
milestone: none → 5.3
Sergey Petrunia (sergefp) wrote :

The cause of the problem is
- a multi-table DELETE attempts to use an index_merge/intersect +"Using index" to read rows.
   = (for single-table DELETE, the problem doesnt show up, because index_merge/intersect is disabled)
- "Using index" means that index_merge will read each column value from its index, and try to assemble a record from them (the record is needed to check the WHERE clause).
- the table is used in DELETE, so table->no_keyread==TRUE. opt_range.cc has this [ancient] code:

int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
{
...
    if (!head->no_keyread)
    {
      doing_key_read= 1;
      head->mark_columns_used_by_index(index);
    }
....

I don't understand the reasoning behind it, but its result is that we will fail to call head->mark_columns_used_by_index(index). This didn't cause the problem up to version 5.2, because opt_range also used old "useless-stub" MRR, which had handler::read_multi_range_first(), which had a call to
table->mark_columns_used_by_index_no_reset(), which fixed things.
However, in 5.3's new MRR we have removed that (because it's generally not needed), and hence this bug.

Sergey Petrunia (sergefp) wrote :

However, if I just move the mark_columns_used_by_index() outside of the if-statement, I get this error with tests:

At line 287: query 'DELETE t1 FROM t1,t2 WHERE t1.c1=0 AND t1.c2=0' failed: 126: Incorrect key file for table './test/t1.MYI'; try to repair it

will need to investigate.

Changed in maria:
status: In Progress → Fix Committed
Sergey Petrunia (sergefp) wrote :

Fix pushed into MariaDB 5.3

Elena Stepanova (elenst) wrote :

Fix released in 5.5.25 and will be in 5.3.8 when it is out

Changed in maria:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers