Bug #42209 Rollback affects the index usage for DELETE statement with FORCE INDEX.
Submitted: 20 Jan 2009 8:30 Modified: 31 Aug 2012 15:44
Reporter: Meiji KIMURA Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S3 (Non-critical)
Version:5.1.30 OS:Any
Assigned to: CPU Architecture:Any

[20 Jan 2009 8:30] Meiji KIMURA
Description:
We cannot use FORCE INDEX for Single-table Syntax of DELETE, but Multiple-table syntax allows
 to use single-table, so we can specify DELETE statement with FORCE INDEX like this,

DELETE t FROM t FORCE INDEX (c1) WHERE c1 < 30;
(or DELETE FROM t USING t FORCE INDEX (c1) WHERE c1 < 30;)

When I use this statement only, DELETE statement use an index properly.
But under some condition, DELETE statement don't use an index even if 'FORCE INDEX' is specified.

I report the bad case with rollback.

[Good case]
create table t (c1 int, c2 varchar(10), key (c1)) engine = innodb;
insert into t (c1, c2) values (10, 'a');
insert into t (c1, c2) values (15, 'a');
insert into t (c1, c2) values (20, 'a');
insert into t (c1, c2) values (25, 'a');
insert into t (c1, c2) values (30, 'a');
insert into t (c1, c2) values (35, 'a');
insert into t (c1, c2) values (40, 'a');
insert into t (c1, c2) values (45, 'a');
insert into t (c1, c2) values (50, 'a');

(1) T1(Transaction1)
set autocommit=0;
begin;
mysql> DELETE t FROM t FORCE INDEX (c1) WHERE c1 < 30;
Query OK, 4 rows affected (0.00 sec)

(2) T2(Transaction2)
set autocommit=0;
begin;
mysql> update t set c2 = 'c' where c1 = 35;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

Process of (1) use a proper index, so Process of (2) works well.

[Bad case]
After Process of (1),(2). Continue to these processes.

(3) T1
rollback;
begin;

(4) T2
rollback;
begin;

(5) T1
mysql> DELETE t FROM t FORCE INDEX (c1) WHERE c1 < 30;
Query OK, 4 rows affected (0.00 sec)

(6) T2
mysql> update t set c2 = 'c' where c1 = 35;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

I checked about lock status of InnoDB by using innoddb_lock_monitor, Process of (5) 
don't use an index and scan a table, so Process (6) wait for the lock to be granted.

[Note]
This problem doesn't occur if INDEX(c1) is Primary Key. 

How to repeat:
See Description:

Suggested fix:
[Work around]
At that case, DELETE statement without FORCE INDEX works well. (The optimizer choose a proper index for DELETE statement)

[Suggested fix]
DELETE statement with FORCE INDEX have to use the index specified anytime.
[21 Jun 2011 1:52] Meiji KIMURA
Under MySQL 5.5.x environment, this problem is solved. (I check it with 5.5.8, 5.5.13).
[31 Aug 2012 15:44] Paul DuBois
Noted in 5.5.8 changelog.

DELETE with FORCE INDEX did not always force the index.