Skip to content

Commit 7b8dcc0

Browse files
MDEV-39440: replay context throwed a warning for a query after altering an index
The problem is that handler->multi_range_read_info_const() call in check_quick_select() returned rows equal to HA_POS_ERROR, both during context capture and replay. However, we never stored the ranges info into the context when rows=HA_POS_ERROR. However, during replay, we try to infuse stats for the given range, and since no match was found in the context, we produced a warning. Solution is to store range_info for all the ranges even when they get HA_POS_ERROR number of rows.
1 parent 467b06c commit 7b8dcc0

3 files changed

Lines changed: 62 additions & 10 deletions

File tree

mysql-test/main/opt_context_replay_basic.result

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,5 +272,28 @@ set optimizer_replay_context='opt_context';
272272
EXPLAIN SELECT MAX(a) FROM t1;
273273
id select_type table type possible_keys key key_len ref rows Extra
274274
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
275+
set optimizer_replay_context='';
276+
drop table t1;
277+
#
278+
# MDEV-39440: replay context doesn't work after altering the index
279+
#
280+
create table t1 (btn char(10) not null, key using HASH (btn)) engine=heap;
281+
insert into t1 values ("a"),("b"),("c"),("d");
282+
alter table t1 add column new_col char(1) not null, add key using HASH (btn,new_col), drop key btn;
283+
update t1 set new_col=left(btn,1);
284+
set optimizer_record_context=1;
285+
explain select * from t1 where btn="a";
286+
id select_type table type possible_keys key key_len ref rows Extra
287+
1 SIMPLE t1 ALL btn NULL NULL NULL 4 Using where
288+
select context into dumpfile "../../tmp/dump1.sql"
289+
from information_schema.optimizer_context;
290+
set optimizer_record_context=0;
291+
drop table t1;
292+
set optimizer_replay_context='opt_context';
293+
# Same query as above, must have same explain:
294+
explain select * from t1 where btn="a";
295+
id select_type table type possible_keys key key_len ref rows Extra
296+
1 SIMPLE t1 ALL btn NULL NULL NULL 4 Using where
297+
set optimizer_replay_context='';
275298
drop table t1;
276299
drop database db1;

mysql-test/main/opt_context_replay_basic.test

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,34 @@ set optimizer_replay_context='opt_context';
116116
--echo # Same query as above, must have same explain:
117117
EXPLAIN SELECT MAX(a) FROM t1;
118118

119+
set optimizer_replay_context='';
120+
--remove_file "$MYSQLTEST_VARDIR/tmp/dump1.sql"
121+
drop table t1;
122+
123+
--echo #
124+
--echo # MDEV-39440: replay context doesn't work after altering the index
125+
--echo #
126+
create table t1 (btn char(10) not null, key using HASH (btn)) engine=heap;
127+
insert into t1 values ("a"),("b"),("c"),("d");
128+
alter table t1 add column new_col char(1) not null, add key using HASH (btn,new_col), drop key btn;
129+
update t1 set new_col=left(btn,1);
130+
131+
set optimizer_record_context=1;
132+
explain select * from t1 where btn="a";
133+
select context into dumpfile "../../tmp/dump1.sql"
134+
from information_schema.optimizer_context;
135+
set optimizer_record_context=0;
136+
drop table t1;
137+
--disable_query_log
138+
--disable_result_log
139+
--source "$MYSQLTEST_VARDIR/tmp/dump1.sql"
140+
--enable_query_log
141+
--enable_result_log
142+
set optimizer_replay_context='opt_context';
143+
--echo # Same query as above, must have same explain:
144+
explain select * from t1 where btn="a";
145+
146+
set optimizer_replay_context='';
119147
--remove_file "$MYSQLTEST_VARDIR/tmp/dump1.sql"
120148
drop table t1;
121149

sql/opt_range.cc

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12471,6 +12471,9 @@ ha_rows check_quick_select(PARAM *param, uint idx, ha_rows limit,
1247112471
ha_rows replay_ctx_max_index_blocks;
1247212472
ha_rows replay_ctx_max_row_blocks;
1247312473
bool replay_ctx_rc;
12474+
TABLE::OPT_RANGE *range= param->table->opt_range + keynr;
12475+
range->max_index_blocks= HA_POS_ERROR;
12476+
range->max_row_blocks= HA_POS_ERROR;
1247412477
DBUG_ENTER("check_quick_select");
1247512478

1247612479
/* Range not calculated yet */
@@ -12534,7 +12537,6 @@ ha_rows check_quick_select(PARAM *param, uint idx, ha_rows limit,
1253412537
param->quick_rows[keynr]= rows;
1253512538
if (rows != HA_POS_ERROR)
1253612539
{
12537-
TABLE::OPT_RANGE *range= param->table->opt_range + keynr;
1253812540
ha_rows table_records= param->table->stat_records();
1253912541
if (rows > table_records)
1254012542
{
@@ -12560,15 +12562,6 @@ ha_rows check_quick_select(PARAM *param, uint idx, ha_rows limit,
1256012562
range->max_row_blocks=
1256112563
MY_MIN(file->row_blocks(), rows * file->stats.block_size / IO_SIZE);
1256212564

12563-
if (Optimizer_context_recorder *rec= param->thd->opt_ctx_recorder)
12564-
{
12565-
Range_print_enumerator_impl range_iter(param, idx, tree);
12566-
rec->record_multi_range_read_info_const(param->table->pos_in_table_list,
12567-
keynr, &range_iter, rows, cost,
12568-
range->max_index_blocks,
12569-
range->max_row_blocks);
12570-
}
12571-
1257212565
if (update_tbl_stats)
1257312566
{
1257412567
param->table->opt_range_keys.set_bit(keynr);
@@ -12597,6 +12590,14 @@ ha_rows check_quick_select(PARAM *param, uint idx, ha_rows limit,
1259712590
}
1259812591
}
1259912592

12593+
if (Optimizer_context_recorder *rec= param->thd->opt_ctx_recorder)
12594+
{
12595+
Range_print_enumerator_impl range_iter(param, idx, tree);
12596+
rec->record_multi_range_read_info_const(
12597+
param->table->pos_in_table_list, keynr, &range_iter, rows, cost,
12598+
range->max_index_blocks, range->max_row_blocks);
12599+
}
12600+
1260012601
/* Figure out if the key scan is ROR (returns rows in ROWID order) or not */
1260112602
enum ha_key_alg key_alg= param->table->key_info[seq.real_keyno].algorithm;
1260212603
if ((key_alg != HA_KEY_ALG_BTREE) && (key_alg!= HA_KEY_ALG_UNDEF))

0 commit comments

Comments
 (0)