Bug #58015 Assert in row_sel_field_store_in_mysql_format when running innodb_mrr_icp test
Submitted: 5 Nov 2010 13:22 Modified: 12 Jan 2011 22:17
Reporter: Olav Sandstå Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S2 (Serious)
Version:5.6.1 OS:Any
Assigned to: Marko Mäkelä CPU Architecture:Any
Tags: index_condition_pushdown, optimizer_switch

[5 Nov 2010 13:22] Olav Sandstå
Description:
When running the innodb_mrr_icp and innodb_mrr_all tests using the lastest source from the mysql-next-mr-opt-backporting tree these tests fails with the following call stack:

  ---- called from signal handler with signal 11 (SIGSEGV) ------
  [8] row_sel_field_store_in_mysql_format(dest = 0xb2ecebd "                                                                                                                                                                                                                            ", templ = 0xb2f245c, data = 0xfe115f96 "AAAAAAAAAA", len = 10U), line 2662 in "row0sel.c"
  [9] row_sel_store_mysql_field(mysql_rec = 0xb2eceb8 "ý", prebuilt = 0xb30a870, rec = 0xfe115f92 "\x80", offsets = 0xfec5aa1c, field_no = 1U, templ = 0xb2f245c), line 2793 in "row0sel.c"
  [10] row_search_idx_cond_check(mysql_rec = 0xb2eceb8 "ý", prebuilt = 0xb30a870, rec = 0xfe115f92 "\x80", offsets = 0xfec5aa1c), line 3370 in "row0sel.c"
  [11] row_search_for_mysql(buf = 0xb2eceb8 "ý", mode = 1U, prebuilt = 0xb30a870, match_mode = 0, direction = 0), line 4424 in "row0sel.c"
  [12] ha_innobase::index_read(this = 0xb2eccf8, buf = 0xb2eceb8 "ý", key_ptr = 0xb2e6f90 "^A", key_len = 5U, find_flag = HA_READ_AFTER_KEY), line 6066 in "ha_innodb.cc"
  [13] handler::index_read_map(this = 0xb2eccf8, buf = 0xb2eceb8 "ý", key = 0xb2e6f90 "^A", keypart_map = 1U, find_flag = HA_READ_AFTER_KEY), line 1805 in "handler.h"
  [14] handler::ha_index_read_map(this = 0xb2eccf8, buf = 0xb2eceb8 "ý", key = 0xb2e6f90 "^A", keypart_map = 1U, find_flag = HA_READ_AFTER_KEY), line 2223 in "handler.cc"
  [15] handler::read_range_first(this = 0xb2eccf8, start_key = 0xb2ecd98, end_key = 0xb2ecda8, eq_range_arg = false, sorted = true), line 5305 in "handler.cc"
  [16] handler::multi_range_read_next(this = 0xb2eccf8, range_info = 0xfec5b264), line 4600 in "handler.cc"
  [17] DsMrr_impl::dsmrr_next(this = 0xb2ece94, range_info = 0xfec5b264), line 4881 in "handler.cc"
  [18] ha_innobase::multi_range_read_next(this = 0xb2eccf8, range_info = 0xfec5b264), line 12264 in "ha_innodb.cc"
  [19] QUICK_RANGE_SELECT::get_next(this = 0xb2f2d58), line 8907 in "opt_range.cc"
  [20] rr_quick(info = 0xb2c3a30), line 338 in "records.cc"
  [21] join_init_read_record(tab = 0xb2c39ec), line 18185 in "sql_select.cc"
  [22] sub_select(join = 0xb2c2c88, join_tab = 0xb2c39ec, end_of_records = false), line 17278 in "sql_select.cc"
  [23] do_select(join = 0xb2c2c88, fields = 0xb281570, table = (nil), procedure = (nil)), line 16827 in "sql_select.cc"
  [24] JOIN::exec(this = 0xb2c2c88), line 3288 in "sql_select.cc"
  [25] mysql_select(thd = 0xb27fe50, rref_pointer_array = 0xb2815e0, tables = 0xb2c20e0, wild_num = 1U, fields = CLASS, conds = 0xb2c2b58, og_num = 0, order = (nil), group = (nil), having = (nil), proc_param = (nil), select_options = 2147748608ULL, result = 0xb2c2c78, unit = 0xb281094, select_lex = 0xb2814dc), line 3496 in "sql_select.cc"
  [26] handle_select(thd = 0xb27fe50, lex = 0xb281030, result = 0xb2c2c78, setup_tables_done_option = 0), line 310 in "sql_select.cc"
  [27] execute_sqlcom_select(thd = 0xb27fe50, all_tables = 0xb2c20e0), line 4494 in "sql_parse.cc"
  [28] mysql_execute_command(thd = 0xb27fe50), line 2092 in "sql_parse.cc"
  [29] mysql_parse(thd = 0xb27fe50, rawbuf = 0xb2c1f50 "select * from t1 where a < 10 and b = repeat(char(65+a), 20)", length = 60U, parser_state = 0xfec5dca0), line 5537 in "sql_parse.cc"
  [30] dispatch_command(command = COM_QUERY, thd = 0xb27fe50, packet = 0xb2b9f21 "", packet_length = 60U), line 1056 in "sql_parse.cc"
  [31] do_command(thd = 0xb27fe50), line 796 in "sql_parse.cc"
  [32] do_handle_one_connection(thd_arg = 0xb27fe50), line 745 in "sql_connect.cc"
  [33] handle_one_connection(arg = 0xb27fe50), line 684 in "sql_connect.cc"
  [34] pfs_spawn_thread(arg = 0xb289470), line 1078 in "pfs.cc"
  [35] _thrp_setup(0xfec95a00), at 0xfeaefa63 
  [36] _lwp_start(0xf, 0xb, 0x0, 0xfeaed64a, 0xfec5a638, 0x8d1d3b4), at 0xfeaefcf0 

The assert that is hit is at the end of row_sel_field_store_in_mysql_format() in row0sel.c line 2662:

   ut_ad(templ->mysql_col_len == len);

How to repeat:
1. Use the latest source from mysql-next-mr-opt-backporting-

2. Compile with debug enabled:

    cmake . -DWITH_DEBUG=1 -DWITH_INNOBASE_STORAGE_ENGINE=1
    gmake

3. mtr innodb_mrr_icp
[5 Nov 2010 14:31] Olav Sandstå
Test case that reproduces this crash (taken from innodb_mrr_icp test):

CREATE TABLE t0 (a INT);
INSERT INTO t0 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);

CREATE TABLE t1 (a INT, b CHAR(20), filler CHAR(200), KEY(a,b(10))) ENGINE=InnoDB;
INSERT INTO t1 SELECT A.a + 10*(B.a + 10*C.a), 'bbb','filler' FROM t0 A, t0 B, t0 C;
UPDATE t1 SET b=REPEAT(char(65+a), 20) WHERE a < 25;

SELECT * FROM t1 WHERE a < 10 AND b = REPEAT(CHAR(65+a), 20);

DROP TABLE t0,t1;
[5 Nov 2010 14:32] Olav Sandstå
Query plan/explain for the failing query:

EXPLAIN SELECT * FROM t1 WHERE a < 10 AND b = REPEAT(CHAR(65+a), 20);
id      select_type     table   type    possible_keys   key     key_len ref     rows    Extra
1       SIMPLE  t1      range   a       a       5       NULL    19      Using index condition; Using where
[5 Nov 2010 14:46] Olav Sandstå
The crash goes away if I disable use of Index Condition Pushdown.
[5 Nov 2010 15:10] Olav Sandstå
The index condition that we push down is:

  `test`.`t1`.`a` < 10

Note that this condition does not involve the b field of the key.
[8 Nov 2010 8:36] Olav Sandstå
Looking at the values that are compared in the failing assert:

ut_ad(templ->mysql_col_len == len);

shows

(dbx) print templ->mysql_col_len
templ->mysql_col_len = 20U
(dbx) print len
len = 10U

These values corresponds well with the size of the b field (CHAR(20)) and the 
size of the prefix of the field b in the index (KEY(a, b(10)).
[8 Nov 2010 12:06] Marko Mäkelä
This is a too strict debug assertion. In the index condition check, we can legitimately return a column prefix to MySQL. If the condition passes, we will convert all columns from the clustered index record to MySQL format, overwriting the column prefix with the full column. The re-conversion is already needed for Bug #56680, to deliver columns of case-insensitive indexes in the correct case.
[5 Dec 2010 12:38] Bugs System
Pushed into mysql-trunk 5.6.1 (revid:alexander.nozdrin@oracle.com-20101205122447-6x94l4fmslpbttxj) (version source revid:alexander.nozdrin@oracle.com-20101205122447-6x94l4fmslpbttxj) (merge vers: 5.6.1) (pib:23)
[9 Dec 2010 5:30] MySQL Verification Team
bug still exists in mysql-trunk (5.6.1) but since the testcase here is incomplete, I made a new testcase.  The charset is important, imho.

drop table if exists `t1`;
create table `t1` (`a` char(2),`b` double,
primary key (`a`(1)),key (`b`)) engine=innodb default charset=utf8;
insert into `t1` values ('',1);
select 1 from `t1` where `b` <= 1 and `a` <> '';
[13 Dec 2010 10:23] Marko Mäkelä
I am testing my patch for this. It was just a bogus debug assertion failure, nothing to worry about. Normally, InnoDB never returns an index prefix to MySQL. In index condition pushdown, we can return an index prefix so that MySQL can evaluate it. (The column will be padded by spaces; only the prefix will be collation-equal to the row. I hope that ICP will never be used when the condition depends on more than the column prefix, or more than collation equality.)
[13 Dec 2010 15:23] 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/126660
[13 Dec 2010 15:23] 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/126661
[22 Dec 2010 21:30] Bugs System
Pushed into mysql-trunk 5.6.1 (revid:alexander.nozdrin@oracle.com-20101222212842-y0t3ibtd32wd9qaw) (version source revid:alexander.nozdrin@oracle.com-20101222212842-y0t3ibtd32wd9qaw) (merge vers: 5.6.1) (pib:24)