Bug #59259 | Incorrect rows returned for a correlated subquery when ICP is on | ||
---|---|---|---|
Submitted: | 3 Jan 2011 12:03 | Modified: | 10 Feb 2011 23:43 |
Reporter: | SaiKumar V | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S2 (Serious) |
Version: | 5.6.1 | OS: | Linux (RedHat x86) |
Assigned to: | Marko Mäkelä | CPU Architecture: | Any |
Tags: | index_condition_pushdown, optimizer_switch |
[3 Jan 2011 12:03]
SaiKumar V
[7 Jan 2011 11:46]
Olav Sandstå
Reduced/simplified version of test case to reproduce the problem: ================================================================= CREATE TABLE t1 ( pk INTEGER NOT NULL, i1 INTEGER NOT NULL ) ENGINE=InnoDB; INSERT INTO t1 VALUES (11,0); INSERT INTO t1 VALUES (12,5); INSERT INTO t1 VALUES (15,0); CREATE TABLE t2 ( pk INTEGER NOT NULL, i1 INTEGER NOT NULL, PRIMARY KEY (pk) ) ENGINE=InnoDB; INSERT INTO t2 VALUES (11,1); INSERT INTO t2 VALUES (12,2); INSERT INTO t2 VALUES (15,4); SELECT * FROM t1 WHERE pk IN ( SELECT it.pk FROM t2 JOIN t2 AS it ON it.i1=it.i1 WHERE t1.i1); DROP TABLE t1, t2;
[10 Jan 2011 14:07]
Olav Sandstå
Explain output for the simplified test case: ============================================ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where 2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using index 2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using index condition
[10 Jan 2011 14:10]
Olav Sandstå
The index condition that gets pushed down to InnoDB when running the simplified test case is pushed down on the table "it" (alias for "t2") for the primary key (pk) index. It contains the following condition: `test`.`t1`.`i1`
[10 Jan 2011 15:12]
Olav Sandstå
The cause for the extra rows in the result set is that an index condition is pushed down to InnoDB on the primary key but this is never evaluated by InnoDB. So in this case the where condition "WHERE t1.i1" is never evaluated neither by InnoDB nor the server and thus the extra rows get included in the result set instead of being filtered out. The problem seems to occur in PHASE 2 of row_search_for_mysql() (in row0sel.c). The retrieval of data from the "it" table (alias for "t2") satisfy the critiera for using the "adaptive hash index search": /*-------------------------------------------------------------*/ /* PHASE 2: Try fast adaptive hash index search if possible */ /* Next test if this is the special case where we can use the fast adaptive hash index to try the search. Since we must release the search system latch when we retrieve an externally stored field, we cannot use the adaptive hash index in a search in the case the row may be long and there may be externally stored fields */ if (UNIV_UNLIKELY(direction == 0) && unique_search && dict_index_is_clust(index) && !prebuilt->templ_contains_blob && !prebuilt->used_in_HANDLER && (prebuilt->mysql_row_len < UNIV_PAGE_SIZE / 8)) { mode = PAGE_CUR_GE; if (trx->mysql_n_tables_locked == 0 && prebuilt->select_lock_type == LOCK_NONE && trx->isolation_level > TRX_ISO_READ_UNCOMMITTED && trx->read_view) { Here InnoDB finds the correct row and will thus first got to the label "release_search_latch_if_needed" and then to the label "func_exit". By jumping directly to "func_exit" the code that checks for index condtions is bypassed and thus the pushed index condition is not evaluated.
[11 Jan 2011 13:22]
Marko Mäkelä
Thank you, Olav! I should have thought about the adaptive hash index when reviewing the ICP code. The adaptive hash index lookup could still make sense with index condition pushdown. The fix should be simple: when row_sel_try_search_shortcut_for_mysql() returns SEL_FOUND, evaluate prebuilt->idx_cond if it exists. This is an InnoDB bug.
[12 Jan 2011 13:47]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/128515
[12 Jan 2011 13:48]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/128516
[30 Jan 2011 16:59]
Bugs System
Pushed into mysql-trunk 5.6.2 (revid:vasil.dimov@oracle.com-20110130165639-1pr3opz839b98q5j) (version source revid:vasil.dimov@oracle.com-20110130165522-m0o6al0pn5ig9kv3) (merge vers: 5.6.2) (pib:24)