Skip to content

Commit 67319f3

Browse files
committed
MDEV-34860 Implement MAX_EXECUTION_TIME hint
It places a limit N (a timeout value in milliseconds) on how long a statement is permitted to execute before the server terminates it. Syntax: SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... Only top-level SELECT statements support the hint.
1 parent 1e2774d commit 67319f3

20 files changed

+573
-51
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#
2+
# MAX_EXECUTION_TIME hint testing
3+
#
4+
CREATE TABLE t1 (a INT, b VARCHAR(300));
5+
INSERT INTO t1 VALUES (1, 'string');
6+
INSERT INTO t1 SELECT * FROM t1;
7+
INSERT INTO t1 SELECT * FROM t1;
8+
INSERT INTO t1 SELECT * FROM t1;
9+
INSERT INTO t1 SELECT * FROM t1;
10+
INSERT INTO t1 SELECT * FROM t1;
11+
INSERT INTO t1 SELECT * FROM t1;
12+
INSERT INTO t1 SELECT * FROM t1;
13+
INSERT INTO t1 SELECT * FROM t1;
14+
INSERT INTO t1 SELECT * FROM t1;
15+
# Correct hint usage
16+
SELECT /*+ MAX_EXECUTION_TIME(10) */* FROM t1 a, t1 b;
17+
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
18+
EXPLAIN EXTENDED SELECT /*+ MAX_EXECUTION_TIME(000149) */* FROM t1;
19+
id select_type table type possible_keys key key_len ref rows filtered Extra
20+
1 SIMPLE t1 ALL NULL NULL NULL NULL 512 100.00
21+
Warnings:
22+
Note 1003 select /*+ MAX_EXECUTION_TIME(000149) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`
23+
SELECT /*+ MAX_EXECUTION_TIME(20) */ *, SLEEP(1) FROM t1 UNION SELECT 1, 2, 3;
24+
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
25+
(SELECT /*+ MAX_EXECUTION_TIME(30) */ *, SLEEP(1) FROM t1) UNION (SELECT 1, 2, 3);
26+
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
27+
((SELECT /*+ MAX_EXECUTION_TIME(50) */ *, SLEEP(1) FROM t1));
28+
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
29+
# Check that prepared statements process the hint correctly
30+
PREPARE s FROM 'SELECT /*+ MAX_EXECUTION_TIME(20) */ seq, SLEEP(1) FROM seq_1_to_10';
31+
EXECUTE s;
32+
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
33+
EXECUTE s;
34+
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
35+
# Hint duplication
36+
SELECT /*+ MAX_EXECUTION_TIME(10) MAX_EXECUTION_TIME(100) */ count(*) FROM t1;
37+
count(*)
38+
512
39+
Warnings:
40+
Warning 4202 Hint MAX_EXECUTION_TIME(100) is ignored as conflicting/duplicated
41+
# Wrong values
42+
SELECT /*+ MAX_EXECUTION_TIME(0) */ count(*) FROM t1;
43+
count(*)
44+
512
45+
Warnings:
46+
Warning 1912 Incorrect value '0' for option 'MAX_EXECUTION_TIME'
47+
SELECT /*+ MAX_EXECUTION_TIME(-1) */ count(*) FROM t1;
48+
count(*)
49+
512
50+
Warnings:
51+
Warning 1064 Optimizer hint syntax error near '-1) */ count(*) FROM t1' at line 1
52+
SELECT /*+ MAX_EXECUTION_TIME(4294967296) */ count(*) FROM t1;
53+
count(*)
54+
512
55+
Warnings:
56+
Warning 1912 Incorrect value '4294967296' for option 'MAX_EXECUTION_TIME'
57+
# Conflicting max_statement_time and hint (must issue a warning)
58+
SET STATEMENT max_statement_time=1 FOR
59+
SELECT /*+ MAX_EXECUTION_TIME(500) */ count(*) FROM t1 a;
60+
count(*)
61+
512
62+
Warnings:
63+
Warning 4202 Hint MAX_EXECUTION_TIME(500) is ignored as conflicting/duplicated
64+
65+
# only SELECT statements supports the MAX_EXECUTION_TIME hint (warning):
66+
67+
CREATE TABLE t2 (i INT);
68+
INSERT /*+ MAX_EXECUTION_TIME(10) */ INTO t2 SELECT 1;
69+
Warnings:
70+
Warning 4172 'MAX_EXECUTION_TIME(10)' is not allowed in this context
71+
REPLACE /*+ MAX_EXECUTION_TIME(15) */ INTO t2 SELECT 1;
72+
Warnings:
73+
Warning 4172 'MAX_EXECUTION_TIME(15)' is not allowed in this context
74+
UPDATE /*+ MAX_EXECUTION_TIME(23) */ t2 SET i = 1;
75+
Warnings:
76+
Warning 4172 'MAX_EXECUTION_TIME(23)' is not allowed in this context
77+
DELETE /*+ MAX_EXECUTION_TIME(5000) */ FROM t2 WHERE i = 1;
78+
Warnings:
79+
Warning 4172 'MAX_EXECUTION_TIME(5000)' is not allowed in this context
80+
# Not supported inside stored procedures/functions
81+
CREATE PROCEDURE p1() BEGIN SELECT /*+ MAX_EXECUTION_TIME(10) */ count(*) FROM t1 a, t1 b
82+
INTO @a; END|
83+
CALL p1();
84+
Warnings:
85+
Warning 4172 'MAX_EXECUTION_TIME(10)' is not allowed in this context
86+
DROP PROCEDURE p1;
87+
# Hint in a subquery is not allowed (warning):
88+
SELECT 1 FROM (SELECT /*+ MAX_EXECUTION_TIME(10) */ 1) a;
89+
1
90+
1
91+
Warnings:
92+
Warning 4172 'MAX_EXECUTION_TIME(10)' is not allowed in this context
93+
# Hint is allowed only for the first select of UNION (warning):
94+
SELECT /*+ MAX_EXECUTION_TIME(20) */ count(*) FROM t1
95+
UNION
96+
SELECT /*+ MAX_EXECUTION_TIME(30) */ count(*) FROM t1;
97+
count(*)
98+
512
99+
Warnings:
100+
Warning 4202 Hint MAX_EXECUTION_TIME(30) is ignored as conflicting/duplicated
101+
SELECT count(*) FROM t1
102+
UNION
103+
SELECT /*+ MAX_EXECUTION_TIME(30) */ count(*) FROM t1;
104+
count(*)
105+
512
106+
Warnings:
107+
Warning 4172 'MAX_EXECUTION_TIME(30)' is not allowed in this context
108+
# Check that hint actually works:
109+
SELECT /*+ MAX_EXECUTION_TIME(20) */ count(*), SLEEP(1) FROM t1
110+
UNION
111+
SELECT count(*), SLEEP(1) FROM t1;
112+
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
113+
DROP TABLE t1, t2;
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
--source include/have_sequence.inc
2+
--echo #
3+
--echo # MAX_EXECUTION_TIME hint testing
4+
--echo #
5+
--enable_prepare_warnings
6+
7+
CREATE TABLE t1 (a INT, b VARCHAR(300));
8+
INSERT INTO t1 VALUES (1, 'string');
9+
INSERT INTO t1 SELECT * FROM t1;
10+
INSERT INTO t1 SELECT * FROM t1;
11+
INSERT INTO t1 SELECT * FROM t1;
12+
INSERT INTO t1 SELECT * FROM t1;
13+
INSERT INTO t1 SELECT * FROM t1;
14+
INSERT INTO t1 SELECT * FROM t1;
15+
INSERT INTO t1 SELECT * FROM t1;
16+
INSERT INTO t1 SELECT * FROM t1;
17+
INSERT INTO t1 SELECT * FROM t1;
18+
19+
-- disable_query_log
20+
-- disable_result_log
21+
analyze table t1;
22+
-- enable_result_log
23+
-- enable_query_log
24+
25+
--echo # Correct hint usage
26+
--error ER_STATEMENT_TIMEOUT
27+
SELECT /*+ MAX_EXECUTION_TIME(10) */* FROM t1 a, t1 b;
28+
29+
EXPLAIN EXTENDED SELECT /*+ MAX_EXECUTION_TIME(000149) */* FROM t1;
30+
31+
--error ER_STATEMENT_TIMEOUT
32+
SELECT /*+ MAX_EXECUTION_TIME(20) */ *, SLEEP(1) FROM t1 UNION SELECT 1, 2, 3;
33+
--error ER_STATEMENT_TIMEOUT
34+
(SELECT /*+ MAX_EXECUTION_TIME(30) */ *, SLEEP(1) FROM t1) UNION (SELECT 1, 2, 3);
35+
--error ER_STATEMENT_TIMEOUT
36+
((SELECT /*+ MAX_EXECUTION_TIME(50) */ *, SLEEP(1) FROM t1));
37+
38+
--echo # Check that prepared statements process the hint correctly
39+
PREPARE s FROM 'SELECT /*+ MAX_EXECUTION_TIME(20) */ seq, SLEEP(1) FROM seq_1_to_10';
40+
--error ER_STATEMENT_TIMEOUT
41+
EXECUTE s;
42+
--error ER_STATEMENT_TIMEOUT
43+
EXECUTE s;
44+
45+
--echo # Hint duplication
46+
47+
SELECT /*+ MAX_EXECUTION_TIME(10) MAX_EXECUTION_TIME(100) */ count(*) FROM t1;
48+
49+
--echo # Wrong values
50+
SELECT /*+ MAX_EXECUTION_TIME(0) */ count(*) FROM t1;
51+
SELECT /*+ MAX_EXECUTION_TIME(-1) */ count(*) FROM t1;
52+
SELECT /*+ MAX_EXECUTION_TIME(4294967296) */ count(*) FROM t1;
53+
54+
--echo # Conflicting max_statement_time and hint (must issue a warning)
55+
SET STATEMENT max_statement_time=1 FOR
56+
SELECT /*+ MAX_EXECUTION_TIME(500) */ count(*) FROM t1 a;
57+
58+
--echo
59+
--echo # only SELECT statements supports the MAX_EXECUTION_TIME hint (warning):
60+
--echo
61+
CREATE TABLE t2 (i INT);
62+
INSERT /*+ MAX_EXECUTION_TIME(10) */ INTO t2 SELECT 1;
63+
REPLACE /*+ MAX_EXECUTION_TIME(15) */ INTO t2 SELECT 1;
64+
UPDATE /*+ MAX_EXECUTION_TIME(23) */ t2 SET i = 1;
65+
DELETE /*+ MAX_EXECUTION_TIME(5000) */ FROM t2 WHERE i = 1;
66+
67+
--echo # Not supported inside stored procedures/functions
68+
DELIMITER |;
69+
CREATE PROCEDURE p1() BEGIN SELECT /*+ MAX_EXECUTION_TIME(10) */ count(*) FROM t1 a, t1 b
70+
INTO @a; END|
71+
DELIMITER ;|
72+
73+
CALL p1();
74+
DROP PROCEDURE p1;
75+
76+
--echo # Hint in a subquery is not allowed (warning):
77+
SELECT 1 FROM (SELECT /*+ MAX_EXECUTION_TIME(10) */ 1) a;
78+
79+
--echo # Hint is allowed only for the first select of UNION (warning):
80+
SELECT /*+ MAX_EXECUTION_TIME(20) */ count(*) FROM t1
81+
UNION
82+
SELECT /*+ MAX_EXECUTION_TIME(30) */ count(*) FROM t1;
83+
84+
SELECT count(*) FROM t1
85+
UNION
86+
SELECT /*+ MAX_EXECUTION_TIME(30) */ count(*) FROM t1;
87+
88+
--echo # Check that hint actually works:
89+
--error ER_STATEMENT_TIMEOUT
90+
SELECT /*+ MAX_EXECUTION_TIME(20) */ count(*), SLEEP(1) FROM t1
91+
UNION
92+
SELECT count(*), SLEEP(1) FROM t1;
93+
94+
DROP TABLE t1, t2;
95+

mysql-test/main/opt_hints.result

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1799,6 +1799,14 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
17991799
Warnings:
18001800
Note 1003 select /*+ QB_NAME(`a
18011801
b`) */ 1 AS `1`
1802+
# Identifiers starting with digits must be supported:
1803+
CREATE OR REPLACE TABLE 0a (8a INT, KEY 6a(8a));
1804+
EXPLAIN EXTENDED SELECT /*+ NO_MRR(0a 6a) BKA(0a)*/ 8a FROM 0a;
1805+
id select_type table type possible_keys key key_len ref rows filtered Extra
1806+
1 SIMPLE 0a system NULL NULL NULL NULL 0 0.00 Const row not found
1807+
Warnings:
1808+
Note 1003 select /*+ BKA(`0a`@`select#1`) NO_MRR(`0a`@`select#1` `6a`) */ NULL AS `8a` from `test`.`0a`
1809+
DROP TABLE 0a;
18021810
# hint syntax error: empty quoted identifier
18031811
EXPLAIN EXTENDED SELECT /*+ QB_NAME(``) */ 1;
18041812
id select_type table type possible_keys key key_len ref rows filtered Extra
@@ -1876,7 +1884,7 @@ SELECT /*+ NO_ICP(10) */ 1;
18761884
1
18771885
1
18781886
Warnings:
1879-
Warning4204 Unresolved table name `10`@`select#1` for NO_ICP hint
1887+
Warning1064 Optimizer hint syntax error near '10) */ 1' at line 1
18801888
SELECT /*+ NO_ICP( */ 1;
18811889
1
18821890
1

mysql-test/main/opt_hints.test

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,11 @@ EXPLAIN EXTENDED SELECT /*+ QB_NAME(`*b`) */ 1;
914914
EXPLAIN EXTENDED SELECT /*+ QB_NAME(`a
915915
b`) */ 1;
916916

917+
--echo # Identifiers starting with digits must be supported:
918+
CREATE OR REPLACE TABLE 0a (8a INT, KEY 6a(8a));
919+
EXPLAIN EXTENDED SELECT /*+ NO_MRR(0a 6a) BKA(0a)*/ 8a FROM 0a;
920+
DROP TABLE 0a;
921+
917922
--echo # hint syntax error: empty quoted identifier
918923
EXPLAIN EXTENDED SELECT /*+ QB_NAME(``) */ 1;
919924

sql/log_event_server.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4857,7 +4857,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
48574857
set/reset the slave thread's timer; a Rows_log_event update needs to set
48584858
the timer itself
48594859
*/
4860-
thd->set_query_timer();
4860+
thd->set_query_timer_if_needed();
48614861

48624862
/*
48634863
If there are no tables open, this must be the first row event seen

0 commit comments

Comments
 (0)