Skip to content

Commit 1ffffac

Browse files
author
Debarun Banerjee
committed
BUG#21864838 SIG11 IN FIELD_BLOB::CMP| AT SQL/FIELD.CC
Bug#21881155: UNINTIALIZED READ IN KEY_REC_CMP CAUSE CRASH LATER Problem : --------- The issue is in generic partition handler that ensures order of fetched records across partitions. It does a n-way merge with the records from multiple partitions with the help of a priority queue. The queue needs to compare records from different partitions based on key (key_rec_cmp). key_rec_cmp() fails if the records contain virtual columns. Solution : ---------- All these comparisons are on the scan keys (virtual columns) from the secondary index. For secondary index scan if we could always return the evaluated secondary index key values in the record then the issues would be resolved. Reviewed-by: Jimmy Yang <[email protected]> RB: 10686
1 parent bcc3a65 commit 1ffffac

File tree

6 files changed

+76
-5
lines changed

6 files changed

+76
-5
lines changed

mysql-test/suite/innodb/r/partition.result

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,3 +518,30 @@ Warning 1013 InnoDB: Trying to get the free space for partition `test`.`t1` /* P
518518
Warning 1013 InnoDB: Trying to get the free space for partition `test`.`t1` /* Partition `p2` */ but its tablespace has been discarded or the .ibd file is missing. Setting the free space of the partition to zero.
519519
Warning 1013 InnoDB: Trying to get the free space for partition `test`.`t1` /* Partition `p3` */ but its tablespace has been discarded or the .ibd file is missing. Setting the free space of the partition to zero.
520520
DROP TABLE t1;
521+
#
522+
# Bug#21864838: SIG11 IN FIELD_BLOB::CMP| AT SQL/FIELD.CC
523+
#
524+
CREATE TABLE t1 (col1 INT PRIMARY KEY, col2 VARCHAR(1), col3 BLOB AS (REPEAT(col2, 500)) VIRTUAL, KEY(col3(100)))
525+
ENGINE=INNODB
526+
PARTITION BY HASH(col1) PARTITIONS 2;
527+
CREATE TABLE t2 (col1 INT PRIMARY KEY, col2 VARCHAR(1), col3 BLOB AS (REPEAT(col2, 500)) VIRTUAL, KEY(col3(100)))
528+
ENGINE=INNODB
529+
PARTITION BY HASH(col1) PARTITIONS 2;
530+
INSERT INTO t1 (col1, col2) VALUES(1, 'd'), (2, 'c'), (3, 'b'), (4, 'a');
531+
INSERT INTO t2 (col1, col2) VALUES(1, 'd'), (2, 'c'), (3, 'b'), (4, 'a');
532+
SELECT t1.col1 FROM t1, t2 where t1.col1 = 3 AND t1.col3 = t2.col3 ORDER BY t2.col1 DESC;
533+
col1
534+
3
535+
DROP TABLE t1;
536+
DROP TABLE t2;
537+
#
538+
# Bug #21881155: UNINTIALIZED READ IN KEY_REC_CMP CAUSE CRASH LATER
539+
#
540+
CREATE TABLE t1 (col1 int, col2 BLOB AS ('a') VIRTUAL, col3 INT,
541+
PRIMARY KEY(col1), KEY (col3, col2(1), col1))
542+
ENGINE=INNODB
543+
PARTITION BY KEY (col1) PARTITIONS 2;
544+
INSERT INTO t1(col1) values (1),(2);
545+
SELECT 1 FROM t1 WHERE col2 > 'a' GROUP BY col3;
546+
1
547+
DROP TABLE t1;

mysql-test/suite/innodb/t/partition.test

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,3 +439,37 @@ ALTER TABLE t1 DISCARD TABLESPACE;
439439
SELECT TABLE_ROWS FROM information_schema.tables where table_name = 't1';
440440

441441
DROP TABLE t1;
442+
443+
--echo #
444+
--echo # Bug#21864838: SIG11 IN FIELD_BLOB::CMP| AT SQL/FIELD.CC
445+
--echo #
446+
447+
CREATE TABLE t1 (col1 INT PRIMARY KEY, col2 VARCHAR(1), col3 BLOB AS (REPEAT(col2, 500)) VIRTUAL, KEY(col3(100)))
448+
ENGINE=INNODB
449+
PARTITION BY HASH(col1) PARTITIONS 2;
450+
451+
CREATE TABLE t2 (col1 INT PRIMARY KEY, col2 VARCHAR(1), col3 BLOB AS (REPEAT(col2, 500)) VIRTUAL, KEY(col3(100)))
452+
ENGINE=INNODB
453+
PARTITION BY HASH(col1) PARTITIONS 2;
454+
455+
INSERT INTO t1 (col1, col2) VALUES(1, 'd'), (2, 'c'), (3, 'b'), (4, 'a');
456+
INSERT INTO t2 (col1, col2) VALUES(1, 'd'), (2, 'c'), (3, 'b'), (4, 'a');
457+
458+
SELECT t1.col1 FROM t1, t2 where t1.col1 = 3 AND t1.col3 = t2.col3 ORDER BY t2.col1 DESC;
459+
460+
DROP TABLE t1;
461+
DROP TABLE t2;
462+
463+
--echo #
464+
--echo # Bug #21881155: UNINTIALIZED READ IN KEY_REC_CMP CAUSE CRASH LATER
465+
--echo #
466+
467+
CREATE TABLE t1 (col1 int, col2 BLOB AS ('a') VIRTUAL, col3 INT,
468+
PRIMARY KEY(col1), KEY (col3, col2(1), col1))
469+
ENGINE=INNODB
470+
PARTITION BY KEY (col1) PARTITIONS 2;
471+
472+
INSERT INTO t1(col1) values (1),(2);
473+
SELECT 1 FROM t1 WHERE col2 > 'a' GROUP BY col3;
474+
475+
DROP TABLE t1;

storage/innobase/handler/ha_innopart.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,6 +1755,9 @@ ha_innopart::index_init(
17551755
m_prebuilt->m_no_prefetch = true;
17561756
}
17571757

1758+
/* For scan across partitions, the keys needs to be materialized */
1759+
m_prebuilt->m_read_virtual_key = true;
1760+
17581761
error = change_active_index(part_id, keynr);
17591762
if (error != 0) {
17601763
destroy_record_priority_queue();
@@ -1786,6 +1789,7 @@ ha_innopart::index_end()
17861789
destroy_record_priority_queue();
17871790
m_prebuilt->m_no_prefetch = false;
17881791
}
1792+
m_prebuilt->m_read_virtual_key = false;
17891793

17901794
DBUG_RETURN(ha_innobase::index_end());
17911795
}

storage/innobase/include/row0mysql.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,8 @@ struct row_prebuilt_t {
896896
/** Disable prefetch. */
897897
bool m_no_prefetch;
898898

899+
/** Return materialized key for secondary index scan */
900+
bool m_read_virtual_key;
899901
};
900902

901903
/** Callback for row_mysql_sys_index_iterate() */

storage/innobase/row/row0mysql.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,7 @@ row_create_prebuilt(
989989
prebuilt->blob_heap = NULL;
990990

991991
prebuilt->m_no_prefetch = false;
992+
prebuilt->m_read_virtual_key = false;
992993

993994
DBUG_RETURN(prebuilt);
994995
}

storage/innobase/row/row0sel.cc

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3228,9 +3228,10 @@ row_sel_store_mysql_rec(
32283228
if (templ->is_virtual && dict_index_is_clust(index)) {
32293229

32303230
/* Skip virtual columns if it is not a covered
3231-
search */
3231+
search or virtual key read is not requested. */
32323232
if (!dict_index_has_virtual(prebuilt->index)
3233-
|| !prebuilt->read_just_key
3233+
|| (!prebuilt->read_just_key
3234+
&& !prebuilt->m_read_virtual_key)
32343235
|| !rec_clust) {
32353236
continue;
32363237
}
@@ -4517,10 +4518,12 @@ row_search_mvcc(
45174518
DBUG_RETURN(DB_CORRUPTION);
45184519
}
45194520

4520-
/* We need to get the virtual row value only if this is covered
4521-
index scan */
4521+
/* We need to get the virtual column values stored in secondary
4522+
index key, if this is covered index scan or virtual key read is
4523+
requested. */
45224524
bool need_vrow = dict_index_has_virtual(prebuilt->index)
4523-
&& prebuilt->read_just_key;
4525+
&& (prebuilt->read_just_key
4526+
|| prebuilt->m_read_virtual_key);
45244527

45254528
/*-------------------------------------------------------------*/
45264529
/* PHASE 0: Release a possible s-latch we are holding on the

0 commit comments

Comments
 (0)