Skip to content

Commit 3e807d2

Browse files
spetruniagrooverdan
authored andcommitted
MDEV-23938: innodb row_search_idx_cond_check handle ICP_ABORTED_BY_USER
- row_search_mvcc() should return DB_INTERRUPTED when it got killed. - Add a syncpoint for the ICP check. - Add test coverage for killed-during-ICP-check scenario Backport of MDEV-22761 fixes for ICP from 10.4 commits: * a6f9564 * c03885c XtraDB was fixed in deb3b9a Reviewer: Daniel Black
1 parent 72cb208 commit 3e807d2

File tree

9 files changed

+176
-6
lines changed

9 files changed

+176
-6
lines changed

mysql-test/include/icp_debug_kill.inc

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
--source include/have_debug.inc
2+
--source include/have_debug_sync.inc
3+
--source include/count_sessions.inc
4+
5+
--disable_warnings
6+
drop table if exists t0,t1,t2;
7+
--enable_warnings
8+
9+
create table t0(a int primary key);
10+
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
11+
12+
create table t1(a int primary key);
13+
insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
14+
15+
create table t2 (
16+
kp1 int,
17+
kp2 int,
18+
col char(100),
19+
key(kp1, kp2)
20+
);
21+
insert into t2 select a, a, a from t1;
22+
23+
select engine from information_schema.tables
24+
where table_schema=database() and table_name='t2';
25+
26+
explain
27+
select * from t2 where kp1 between 10 and 20 and kp2 +1 >100;
28+
29+
let $target_id= `select connection_id()`;
30+
31+
set debug_sync='handler_index_cond_check SIGNAL at_icp_check WAIT_FOR go';
32+
send
33+
select * from t2 where kp1 between 10 and 20 and kp2 +1 >100;
34+
35+
connect (con1, localhost, root,,);
36+
connection con1;
37+
set debug_sync='now WAIT_FOR at_icp_check';
38+
evalp kill query $target_id;
39+
set debug_sync='now SIGNAL go';
40+
41+
connection default;
42+
43+
--error ER_QUERY_INTERRUPTED
44+
reap;
45+
set debug_sync='RESET';
46+
47+
disconnect con1;
48+
drop table t0,t1,t2;
49+
--source include/wait_until_count_sessions.inc
50+

mysql-test/t/aria_icp_debug.result

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
set default_storage_engine=aria;
2+
drop table if exists t0,t1,t2;
3+
create table t0(a int primary key);
4+
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
5+
create table t1(a int primary key);
6+
insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
7+
create table t2 (
8+
kp1 int,
9+
kp2 int,
10+
col char(100),
11+
key(kp1, kp2)
12+
);
13+
insert into t2 select a, a, a from t1;
14+
select engine from information_schema.tables
15+
where table_schema=database() and table_name='t2';
16+
engine
17+
Aria
18+
explain
19+
select * from t2 where kp1 between 10 and 20 and kp2 +1 >100;
20+
id select_type table type possible_keys key key_len ref rows Extra
21+
1 SIMPLE t2 range kp1 kp1 5 NULL 10 Using index condition
22+
set debug_sync='handler_index_cond_check SIGNAL at_icp_check WAIT_FOR go';
23+
select * from t2 where kp1 between 10 and 20 and kp2 +1 >100;
24+
connect con1, localhost, root,,;
25+
connection con1;
26+
set debug_sync='now WAIT_FOR at_icp_check';
27+
kill query $target_id;
28+
set debug_sync='now SIGNAL go';
29+
connection default;
30+
ERROR 70100: Query execution was interrupted
31+
set debug_sync='RESET';
32+
disconnect con1;
33+
drop table t0,t1,t2;
34+
set default_storage_engine=default;

mysql-test/t/aria_icp_debug.test

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
set default_storage_engine=aria;
3+
--source include/icp_debug_kill.inc
4+
set default_storage_engine=default;
5+

mysql-test/t/innodb_icp_debug.result

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
set default_storage_engine=innodb;
2+
drop table if exists t0,t1,t2;
3+
create table t0(a int primary key);
4+
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
5+
create table t1(a int primary key);
6+
insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
7+
create table t2 (
8+
kp1 int,
9+
kp2 int,
10+
col char(100),
11+
key(kp1, kp2)
12+
);
13+
insert into t2 select a, a, a from t1;
14+
select engine from information_schema.tables
15+
where table_schema=database() and table_name='t2';
16+
engine
17+
InnoDB
18+
explain
19+
select * from t2 where kp1 between 10 and 20 and kp2 +1 >100;
20+
id select_type table type possible_keys key key_len ref rows Extra
21+
1 SIMPLE t2 range kp1 kp1 5 NULL 11 Using index condition
22+
set debug_sync='handler_index_cond_check SIGNAL at_icp_check WAIT_FOR go';
23+
select * from t2 where kp1 between 10 and 20 and kp2 +1 >100;
24+
connect con1, localhost, root,,;
25+
connection con1;
26+
set debug_sync='now WAIT_FOR at_icp_check';
27+
kill query $target_id;
28+
set debug_sync='now SIGNAL go';
29+
connection default;
30+
ERROR 70100: Query execution was interrupted
31+
set debug_sync='RESET';
32+
disconnect con1;
33+
drop table t0,t1,t2;
34+
set default_storage_engine=default;

mysql-test/t/innodb_icp_debug.test

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
--source include/have_innodb.inc
2+
3+
set default_storage_engine=innodb;
4+
--source include/icp_debug_kill.inc
5+
set default_storage_engine=default;
6+

mysql-test/t/myisam_icp_debug.result

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
drop table if exists t0,t1,t2;
2+
create table t0(a int primary key);
3+
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
4+
create table t1(a int primary key);
5+
insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
6+
create table t2 (
7+
kp1 int,
8+
kp2 int,
9+
col char(100),
10+
key(kp1, kp2)
11+
);
12+
insert into t2 select a, a, a from t1;
13+
select engine from information_schema.tables
14+
where table_schema=database() and table_name='t2';
15+
engine
16+
MyISAM
17+
explain
18+
select * from t2 where kp1 between 10 and 20 and kp2 +1 >100;
19+
id select_type table type possible_keys key key_len ref rows Extra
20+
1 SIMPLE t2 range kp1 kp1 5 NULL 11 Using index condition
21+
set debug_sync='handler_index_cond_check SIGNAL at_icp_check WAIT_FOR go';
22+
select * from t2 where kp1 between 10 and 20 and kp2 +1 >100;
23+
connect con1, localhost, root,,;
24+
connection con1;
25+
set debug_sync='now WAIT_FOR at_icp_check';
26+
kill query $target_id;
27+
set debug_sync='now SIGNAL go';
28+
connection default;
29+
ERROR 70100: Query execution was interrupted
30+
set debug_sync='RESET';
31+
disconnect con1;
32+
drop table t0,t1,t2;

mysql-test/t/myisam_icp_debug.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--source include/icp_debug_kill.inc

sql/handler.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5519,6 +5519,7 @@ extern "C" enum icp_result handler_index_cond_check(void* h_arg)
55195519
THD *thd= h->table->in_use;
55205520
enum icp_result res;
55215521

5522+
DEBUG_SYNC(thd, "handler_index_cond_check");
55225523
enum thd_kill_levels abort_at= h->has_transactions() ?
55235524
THD_ABORT_SOFTLY : THD_ABORT_ASAP;
55245525
if (thd_kill_level(thd) > abort_at)

storage/innobase/row/row0sel.cc

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3588,7 +3588,7 @@ row_sel_try_search_shortcut_for_mysql(
35883588

35893589
/*********************************************************************//**
35903590
Check a pushed-down index condition.
3591-
@return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */
3591+
@return ICP_ABORTED_BY_USER, ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */
35923592
static
35933593
enum icp_result
35943594
row_search_idx_cond_check(
@@ -4110,10 +4110,13 @@ row_search_for_mysql(
41104110
switch (row_search_idx_cond_check(
41114111
buf, prebuilt,
41124112
rec, offsets)) {
4113-
case ICP_NO_MATCH:
4114-
case ICP_OUT_OF_RANGE:
41154113
case ICP_ABORTED_BY_USER:
4114+
mtr_commit(&mtr);
4115+
err = DB_INTERRUPTED;
4116+
goto release_search_latch_if_needed;
41164117
case ICP_ERROR:
4118+
case ICP_NO_MATCH:
4119+
case ICP_OUT_OF_RANGE:
41174120
goto shortcut_mismatch;
41184121
case ICP_MATCH:
41194122
goto shortcut_match;
@@ -4849,8 +4852,10 @@ row_search_for_mysql(
48494852
buf, prebuilt, rec, offsets)) {
48504853
case ICP_NO_MATCH:
48514854
goto next_rec;
4852-
case ICP_OUT_OF_RANGE:
48534855
case ICP_ABORTED_BY_USER:
4856+
err = DB_INTERRUPTED;
4857+
goto idx_cond_failed;
4858+
case ICP_OUT_OF_RANGE:
48544859
case ICP_ERROR:
48554860
err = DB_RECORD_NOT_FOUND;
48564861
goto idx_cond_failed;
@@ -4904,9 +4909,11 @@ row_search_for_mysql(
49044909
row_unlock_for_mysql(prebuilt, TRUE);
49054910
}
49064911
goto next_rec;
4912+
case ICP_ABORTED_BY_USER:
4913+
err = DB_INTERRUPTED;
4914+
goto idx_cond_failed;
49074915
case ICP_OUT_OF_RANGE:
4908-
case ICP_ABORTED_BY_USER:
4909-
case ICP_ERROR:
4916+
case ICP_ERROR:
49104917
err = DB_RECORD_NOT_FOUND;
49114918
goto idx_cond_failed;
49124919
case ICP_MATCH:

0 commit comments

Comments
 (0)