Skip to content

Commit

Permalink
Fixing index_merge query returning wrong results (#624)
Browse files Browse the repository at this point in the history
Summary:
This diff fixed MyRocks returning missing rows if index
merge query plan was used. When index merge is selected,
table->read_map is cleared at
QUICK_RANGE_SELECT::init_ror_merged_scan(). Then
ha_rocksdb::setup_read_decoders() wrongly decided not to decode
all fields, which made MySQL layer decide that keys did not match.
This diff changes ha_rocksdb::setup_read_decoders() to
always decode if read_map is cleared. A side effect is decoding
all fetched fields on index merge. There is a slight performance
penalty but much better than returning wrong results.

This diff reuses index_merge_ror.inc and index_merge_2sweeps.inc
test cases for MyRocks. Since MyRocks query plan is less stable than
InnoDB, it skips using explain and just verifies data correctness.
Closes #626

Reviewed By: hermanlee

Differential Revision: D5088547

Pulled By: yoshinorim

fbshipit-source-id: f025617
  • Loading branch information
yoshinorim authored and facebook-github-bot committed May 18, 2017
1 parent b230a2f commit ee503a8
Show file tree
Hide file tree
Showing 9 changed files with 1,627 additions and 15 deletions.
9 changes: 9 additions & 0 deletions mysql-test/include/index_merge2.inc
Original file line number Diff line number Diff line change
Expand Up @@ -147,22 +147,28 @@ analyze table t2;
-- enable_result_log
-- enable_query_log

if (!$skip_ror_EXPLAIN_for_MyRocks)
{
if ($index_merge_random_rows_in_EXPLAIN)
{
--replace_column 9 #
}
explain select count(*) from t1 where
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
}

select count(*) from t1 where
key1a = 2 and key1b is null and key2a = 2 and key2b is null;

if (!$skip_ror_EXPLAIN_for_MyRocks)
{
if ($index_merge_random_rows_in_EXPLAIN)
{
--replace_column 9 #
}
explain select count(*) from t1 where
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
}

select count(*) from t1 where
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
Expand Down Expand Up @@ -377,12 +383,15 @@ analyze table t1;
-- enable_result_log
-- enable_query_log

if (!$skip_ror_EXPLAIN_for_MyRocks)
{
if ($index_merge_random_rows_in_EXPLAIN)
{
--replace_column 9 #
}
# to test the bug, the following must use "sort_union":
explain select * from t1 where (key3 > 30 and key3<35) or (key2 >32 and key2 < 40);
}
select * from t1 where (key3 > 30 and key3<35) or (key2 >32 and key2 < 40);
drop table t1;

Expand Down
15 changes: 15 additions & 0 deletions mysql-test/include/index_merge_2sweeps.inc
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,38 @@ while ($1)
}
--enable_query_log

if ($sorted_result) {
--sorted_result
}
select * from t1 where (key1 >= 2 and key1 <= 10) or (pk >= 4 and pk <=8 );

set @maxv=1000;

if ($sorted_result) {
--sorted_result
}
select * from t1 where
(pk < 5) or (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 ) or (pk > @maxv-10)
or key1=18 or key1=60;

if ($sorted_result) {
--sorted_result
}
select * from t1 where
(pk < 5) or (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 ) or (pk > @maxv-10)
or key1 < 3 or key1 > @maxv-11;

if ($sorted_result) {
--sorted_result
}
select * from t1 where
(pk < 5) or (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 ) or (pk > @maxv-10)
or
(key1 < 5) or (key1 > 10 and key1 < 15) or (key1 >= 50 and key1 < 55 ) or (key1 > @maxv-10);

if ($sorted_result) {
--sorted_result
}
select * from t1 where
(pk > 10 and pk < 15) or (pk >= 50 and pk < 55 )
or
Expand Down
79 changes: 64 additions & 15 deletions mysql-test/include/index_merge_ror.inc
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,11 @@ analyze table t1;
# One row results tests for cases where a single row matches all conditions
explain select key1,key2 from t1 where key1=100 and key2=100;
select key1,key2 from t1 where key1=100 and key2=100;
explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
explain format=json select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
if (!$skip_ror_EXPLAIN_for_MyRocks)
{
explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
explain format=json select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
}
select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;

# Several-rows results
Expand All @@ -142,26 +145,44 @@ analyze table t1;
-- enable_query_log

# ROR-intersection, not covering
explain select key1,key2,filler1 from t1 where key1=100 and key2=100;
if (!$skip_ror_EXPLAIN_for_MyRocks)
{
explain select key1,key2,filler1 from t1 where key1=100 and key2=100;
}
select key1,key2,filler1 from t1 where key1=100 and key2=100;

# ROR-intersection, covering
explain select key1,key2 from t1 where key1=100 and key2=100;
if (!$skip_ror_EXPLAIN_for_MyRocks)
{
explain select key1,key2 from t1 where key1=100 and key2=100;
}
select key1,key2 from t1 where key1=100 and key2=100;

# ROR-union of ROR-intersections
explain select key1,key2,key3,key4 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
if (!$skip_ror_EXPLAIN_for_MyRocks)
{
explain select key1,key2,key3,key4 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
}
select key1,key2,key3,key4 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
if (!$skip_ror_EXPLAIN_for_MyRocks)
{
explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
}
select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;

# 3-way ROR-intersection
explain select key1,key2,key3 from t1 where key1=100 and key2=100 and key3=100;
if (!$skip_ror_EXPLAIN_for_MyRocks)
{
explain select key1,key2,key3 from t1 where key1=100 and key2=100 and key3=100;
}
select key1,key2,key3 from t1 where key1=100 and key2=100 and key3=100;

# ROR-union(ROR-intersection, ROR-range)
insert into t1 (key1,key2,key3,key4,filler1) values (101,101,101,101, 'key1234-101');
explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=101;
if (!$skip_ror_EXPLAIN_for_MyRocks)
{
explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=101;
}
select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=101;

# Run some ROR updates/deletes
Expand All @@ -178,7 +199,10 @@ select key1,key2,filler1 from t1 where key2=100 and key2=200;

# ROR-union(ROR-intersection) with one of ROR-intersection giving empty
# results
explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
if (!$skip_ror_EXPLAIN_for_MyRocks)
{
explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
}
select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;

delete from t1 where key3=100 and key4=100;
Expand All @@ -190,11 +214,17 @@ analyze table t1;
-- enable_query_log

# ROR-union with all ROR-intersections giving empty results
explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
if (!$skip_ror_EXPLAIN_for_MyRocks)
{
explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
}
select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;

# ROR-intersection with empty result
explain select key1,key2 from t1 where key1=100 and key2=100;
if (!$skip_ror_EXPLAIN_for_MyRocks)
{
explain select key1,key2 from t1 where key1=100 and key2=100;
}
select key1,key2 from t1 where key1=100 and key2=100;

# ROR-union tests with various cases.
Expand All @@ -209,7 +239,10 @@ analyze table t1;
-- enable_result_log
-- enable_query_log

explain select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200;
if (!$skip_ror_EXPLAIN_for_MyRocks)
{
explain select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200;
}
select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200;

insert into t1 (key1, key2, key3, key4, filler1) values (-1, -1, -1, 200,'key4');
Expand All @@ -220,7 +253,10 @@ analyze table t1;
-- enable_result_log
-- enable_query_log

explain select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200;
if (!$skip_ror_EXPLAIN_for_MyRocks)
{
explain select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200;
}
select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200;

insert into t1 (key1, key2, key3, key4, filler1) values (-1, -1, 200, -1,'key3');
Expand All @@ -231,7 +267,10 @@ analyze table t1;
-- enable_result_log
-- enable_query_log

explain select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200;
if (!$skip_ror_EXPLAIN_for_MyRocks)
{
explain select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200;
}
select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200;

##
Expand All @@ -250,11 +289,20 @@ if (!$index_merge_random_rows_in_EXPLAIN)
# Do many tests
# Check that keys that don't improve selectivity are skipped.
#

if (!$skip_ror_EXPLAIN_for_MyRocks)
{
# Different value on 32 and 64 bit
if ($random_rows_in_EXPLAIN)
{
--replace_column 9 #
}
--replace_result sta_swt12a sta_swt21a sta_swt12a, sta_swt12a,
explain select * from t1 where st_a=1 and swt1a=1 and swt2a=1;

if ($random_rows_in_EXPLAIN)
{
--replace_column 9 #
}
explain select * from t1 where st_b=1 and swt1b=1 and swt2b=1;

if ($index_merge_random_rows_in_EXPLAIN)
Expand Down Expand Up @@ -311,6 +359,7 @@ if ($index_merge_random_rows_in_EXPLAIN)
}
explain select st_a from t1
where st_a=1 and swt1a=1 and st_b=1 and swt1b=1 and swt1b=1;
}

drop table t0,t1;

Expand Down
23 changes: 23 additions & 0 deletions mysql-test/suite/rocksdb/r/index_merge_rocksdb.result
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,26 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge key1,key2 key1,key2 5,5 NULL # Using intersect(key1,key2); Using where
UPDATE t1 SET filler1='to be deleted' WHERE key1=100 and key2=100;
DROP TABLE t0, t1;
create table t1 (key1 int, key2 int, key3 int, key (key1), key (key2), key(key3)) engine=rocksdb;
insert into t1 values (1, 100, 100), (1, 200, 200), (1, 300, 300);
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
set global rocksdb_force_flush_memtable_now=1;
explain select * from t1 where key1 = 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref key1 key1 5 const # NULL
explain select key1,key2 from t1 where key1 = 1 or key2 = 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge key1,key2 key1,key2 5,5 NULL # Using union(key1,key2); Using where
select * from t1 where key1 = 1;
key1 key2 key3
1 100 100
1 200 200
1 300 300
select key1,key2 from t1 where key1 = 1 or key2 = 1;
key1 key2
1 100
1 200
1 300
drop table t1;
Loading

0 comments on commit ee503a8

Please sign in to comment.