Details
-
Bug
-
Status: Closed (View Workflow)
-
Critical
-
Resolution: Fixed
-
10.0.12
Description
I believe that Mrr_ordered_index_reader::resume_read() is using saved_primary_key uninitialized if the current read hasn't been interrupted. This manifests itself in our case with the following case:
SET SESSION
|
optimizer_switch="mrr=on,mrr_sort_keys=on",
|
join_cache_level=8;
|
|
SELECT DISTINCT a.x FROM a LEFT JOIN b ON (a.x = b.x) WHERE ...
|
Our query produces an EXPLAIN containing:
"Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan"
|
With the result of the query we get many warnings like:
"Warning 1366 Incorrect string value: '\xE6S\x01\x00\x00\x00...' for column 'y' at row 93"
|
This is because the buffer being purported to be column 'y' is uninitialized or random data, and doesn't pass as valid UTF-8.
Unfortunately I don't have a minimal test case for this yet, but I am able to reproduce it with sensitive data locally and can prove that the below patch fixes the symptom.
Patch follows:
--- sql/multi_range_read.cc 2014-07-10 23:01:30.000000000 -0700
|
+++ sql/multi_range_read.cc 2014-10-15 19:34:56.000000000 -0700
|
@@ -467,6 +467,9 @@ void Mrr_ordered_index_reader::position(
|
|
void Mrr_ordered_index_reader::resume_read()
|
{
|
+ if (have_saved_rowid == FALSE)
|
+ return;
|
+
|
TABLE *table= file->get_table();
|
KEY *used_index= &table->key_info[file->active_index];
|
key_restore(table->record[0], saved_key_tuple,
|
@@ -477,6 +480,8 @@ void Mrr_ordered_index_reader::resume_re
|
&table->key_info[table->s->primary_key],
|
table->key_info[table->s->primary_key].key_length);
|
}
|
+
|
+ have_saved_rowid= FALSE;
|
}
|
I could create a small testcase:
create table ten(a int);
insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t14 (
pk varchar(32) character set utf8 primary key,
kp1 char(32) not null,
col1 varchar(32),
key (kp1)
);
insert into t14
select
concat('pk-', 1000 +A.a),
concat('kp1-', 1000 +A.a),
concat('val-', 1000 +A.a)
from test.ten A ;
create table t16 as select kp1 as a from t14;
set join_cache_level=8;
set optimizer_switch='mrr=on,mrr_sort_keys=on';
select * from t16 straight_join t14 force index(kp1) where t14.kp1=t16.a;
show warnings;
+---------+------+---------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------------------------------------------+
| Warning | 1366 | Incorrect string value: '\xA5\xA5\xA5\xA5\xA5\xA5...' for column 'pk' at row 11 |
+---------+------+---------------------------------------------------------------------------------+
explain select * from t16 straight_join t14 force index(kp1) where t14.kp1=t16.a;
+------+-------------+-------+------+---------------+------+---------+-----------+------+---------------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+-----------+------+---------------------------------------------------------------------+
| 1 | SIMPLE | t16 | ALL | NULL | NULL | NULL | NULL | 10 | |
| 1 | SIMPLE | t14 | ref | kp1 | kp1 | 32 | j12.t16.a | 1 | Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan |
+------+-------------+-------+------+---------------+------+---------+-----------+------+---------------------------------------------------------------------+