Skip to content

Commit

Permalink
Fixing index_merge query returning wrong results (facebook#624) (face…
Browse files Browse the repository at this point in the history
…book#626) [non-RocksDB part]

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 facebook#626

Differential Revision: D5088547

Pulled By: yoshinorim
  • Loading branch information
yoshinorim authored and inikep committed May 24, 2024
1 parent 4983f0a commit 8b67d7c
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 26 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 @@ -148,6 +148,8 @@ analyze table t2;
-- enable_result_log
-- enable_query_log

if (!$skip_ror_EXPLAIN_for_MyRocks)
{
if ($index_merge_random_rows_in_EXPLAIN)
{
--replace_column 10 #
Expand All @@ -160,10 +162,13 @@ if ($engine_type == MyISAM)
}
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 10 #
Expand All @@ -175,6 +180,7 @@ if ($engine_type == MyISAM) {
}
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 @@ -389,12 +395,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 10 #
}
# 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
103 changes: 77 additions & 26 deletions mysql-test/include/index_merge_ror.inc
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,17 @@ if ($index_merge_random_rows_in_EXPLAIN)
}
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;
# Mask cost values since it varies between runs how much of the indexes
# are cached in InnoDB's buffer pool
--skip_if_hypergraph # Depends on the query plan.
--replace_regex /(_cost": )"[0-9.]+"/\1"#"/
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;
# Mask cost values since it varies between runs how much of the indexes
# are cached in InnoDB's buffer pool
--skip_if_hypergraph # Depends on the query plan.
--replace_regex /(_cost": )"[0-9.]+"/\1"#"/
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;

--echo # Several-rows results
Expand All @@ -151,34 +156,52 @@ analyze table t1;
-- enable_query_log

--echo # ROR-intersection, not covering
if ($index_merge_random_rows_in_EXPLAIN)
if (!$skip_ror_EXPLAIN_for_MyRocks)
{
--replace_column 10 # 11 #
if ($index_merge_random_rows_in_EXPLAIN)
{
--replace_column 10 # 11 #
}
explain select key1,key2,filler1 from t1 where key1=100 and key2=100;
}
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;

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

--echo # ROR-union of ROR-intersections
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;

--echo # 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;

--echo # 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;

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

--echo # ROR-union(ROR-intersection) with one of ROR-intersection giving empty
--echo # 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 @@ -209,16 +235,22 @@ analyze table t1;
--echo # ROR-union with all ROR-intersections giving empty results
# The relative order of keys inside
# "Using union(intersect(keyx,keyx),...)" doesn't matter
--replace_result key2,key1 key1,key2 key4,key3 key3,key4
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;
if (!$skip_ror_EXPLAIN_for_MyRocks)
{
--replace_result key2,key1 key1,key2 key4,key3 key3,key4
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;
}

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

--echo # ROR-union tests with various cases.
Expand All @@ -233,7 +265,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 @@ -244,7 +279,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 @@ -255,7 +293,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;

--echo ##
Expand All @@ -274,11 +315,20 @@ if (!$index_merge_random_rows_in_EXPLAIN)
--echo # Do many tests
--echo # 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 @@ -335,6 +385,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

0 comments on commit 8b67d7c

Please sign in to comment.