385 lines
11 KiB
Plaintext
385 lines
11 KiB
Plaintext
# WL#6936 - Implementation of server-side statement timeout
|
|
|
|
--source include/have_statement_timeout.inc
|
|
--source include/have_debug.inc
|
|
|
|
# Save the initial number of concurrent sessions.
|
|
--source include/count_sessions.inc
|
|
|
|
--echo #
|
|
--echo # 1. Test MAX_EXECUTION_TIME option syntax.
|
|
--echo #
|
|
|
|
CREATE TABLE t1 (a INT);
|
|
INSERT INTO t1 VALUES (10);
|
|
|
|
SET @var= (SELECT /*+ MAX_EXECUTION_TIME(0) */ 1);
|
|
SELECT 1 FROM t1 WHERE a IN (SELECT /*+ MAX_EXECUTION_TIME(0) */ 1);
|
|
|
|
SELECT (SELECT /*+ MAX_EXECUTION_TIME(0) */ a FROM t1);
|
|
SELECT a FROM t1 WHERE a IN (SELECT /*+ MAX_EXECUTION_TIME(0) */ a FROM t1);
|
|
SELECT * FROM t1 WHERE a IN (SELECT /*+ MAX_EXECUTION_TIME(0) */ a FROM t1);
|
|
SELECT /*+ MAX_EXECUTION_TIME(0) */ * FROM t1
|
|
WHERE a IN (SELECT /*+ MAX_EXECUTION_TIME(0) */ a FROM t1);
|
|
SELECT * FROM t1
|
|
WHERE a IN (SELECT a FROM t1 UNION SELECT /*+ MAX_EXECUTION_TIME(0) */ a FROM t1);
|
|
SELECT /*+ MAX_EXECUTION_TIME(0) */ * FROM t1
|
|
WHERE a IN (SELECT a FROM t1 UNION SELECT /*+ MAX_EXECUTION_TIME(0) */ a FROM t1);
|
|
|
|
SELECT * FROM t1 UNION SELECT /*+ MAX_EXECUTION_TIME(0) */ * FROM t1;
|
|
SELECT /*+ MAX_EXECUTION_TIME(0) */ * FROM t1
|
|
UNION SELECT /*+ MAX_EXECUTION_TIME(0) */ * FROM t1;
|
|
INSERT INTO t1 SELECT /*+ MAX_EXECUTION_TIME(0) */ * FROM t1;
|
|
CREATE TABLE t2 AS SELECT /*+ MAX_EXECUTION_TIME(0) */ * FROM t1;
|
|
CREATE TABLE t3 AS SELECT 1 A UNION SELECT 2 UNION SELECT /*+ MAX_EXECUTION_TIME(0) */ 3;
|
|
CREATE TABLE /*+ MAX_EXECUTION_TIME(100) */ t4 (a int);
|
|
CREATE /*+ MAX_EXECUTION_TIME(100) */ TABLE t5 (a int);
|
|
DELETE /*+ MAX_EXECUTION_TIME(100) */ FROM t1;
|
|
UPDATE /*+ MAX_EXECUTION_TIME(100) */ t1 SET a=20;
|
|
ALTER TABLE /*+ MAX_EXECUTION_TIME(100) */ t1 ADD b VARCHAR(200);
|
|
ALTER /*+ MAX_EXECUTION_TIME(100) */ TABLE t1 ADD c VARCHAR(200);
|
|
|
|
SELECT /*+ MAX_EXECUTION_TIME(0) */ * FROM t1;
|
|
|
|
DROP TABLE t1, t2, t3, t4, t5;
|
|
|
|
--echo #
|
|
--echo # 2. Test MAX_EXECUTION_TIME value set at session level.
|
|
--echo #
|
|
# Statement level timeout value setting.
|
|
SELECT @@max_execution_time;
|
|
SET @@SESSION.max_execution_time= 1000;
|
|
SELECT @@max_execution_time;
|
|
SET @@SESSION.max_execution_time= 0;
|
|
|
|
--echo #
|
|
--echo # 3. Test the MAX_EXECUTION_TIME option by setting value for it at,
|
|
--echo # - STATEMENT
|
|
--echo # - SESSION
|
|
--echo #
|
|
|
|
# timeout value set at statement level.
|
|
SELECT /*+ MAX_EXECUTION_TIME(1000) */ SLEEP(5);
|
|
|
|
# timeout value set at session level.
|
|
SET @@SESSION.max_execution_time= 1000;
|
|
SELECT SLEEP(5);
|
|
SET @@SESSION.max_execution_time= 0;
|
|
|
|
--echo #
|
|
--echo # 4. Test statement timeout functionality.
|
|
--echo #
|
|
|
|
# Create table t1 for testing.
|
|
CREATE TABLE t1 (a INT, b VARCHAR(300));
|
|
|
|
# Populate table.
|
|
INSERT INTO t1 VALUES (1, 'string');
|
|
INSERT INTO t1 SELECT * FROM t1;
|
|
INSERT INTO t1 SELECT * FROM t1;
|
|
INSERT INTO t1 SELECT * FROM t1;
|
|
INSERT INTO t1 SELECT * FROM t1;
|
|
INSERT INTO t1 SELECT * FROM t1;
|
|
INSERT INTO t1 SELECT * FROM t1;
|
|
INSERT INTO t1 SELECT * FROM t1;
|
|
INSERT INTO t1 SELECT * FROM t1;
|
|
INSERT INTO t1 SELECT * FROM t1;
|
|
INSERT INTO t1 SELECT * FROM t1;
|
|
INSERT INTO t1 SELECT * FROM t1;
|
|
|
|
# Set Session max_execution_time to 2 millisecond
|
|
SET @@SESSION.max_execution_time= 2;
|
|
|
|
# Case 4.1: Following select should timeout
|
|
--error ER_QUERY_TIMEOUT
|
|
SELECT *, SLEEP(0.5) from t1;
|
|
|
|
# Case 4.2: MDL lock request wait is interrupted on timeout.
|
|
connect(con1, localhost, root,,);
|
|
LOCK TABLE t1 WRITE;
|
|
|
|
connection default;
|
|
# Following select should timeout
|
|
--error ER_QUERY_TIMEOUT
|
|
SELECT * FROM t1;
|
|
|
|
# Following select should timeout
|
|
--error ER_QUERY_TIMEOUT
|
|
SELECT /*+ MAX_EXECUTION_TIME(1) */ * FROM t1;
|
|
|
|
connection con1;
|
|
UNLOCK TABLES;
|
|
connection default;
|
|
disconnect con1;
|
|
|
|
# Case 4.3: max_execution_time is not applicable to DDL statement.
|
|
CREATE TABLE t2 SELECT * FROM t1;
|
|
ALTER TABLE t2 ADD c VARCHAR(200) default 'new_col';
|
|
|
|
# Case 4.4: max_execution_time is not applicable to UPDATE statement.
|
|
UPDATE t1 SET b= 'new_string';
|
|
|
|
# Case 4.5: max_execution_time is not applicable to INSERT statement.
|
|
INSERT INTO t1 SELECT * FROM t1;
|
|
|
|
# Case 4.6: max_execution_time is not applicable to DELETE statement.
|
|
DELETE FROM t2;
|
|
|
|
--echo #
|
|
--echo # 5. Test SELECT with subquery.
|
|
--echo #
|
|
|
|
# Timeout is not applicable to subqueries.
|
|
SELECT /*+ MAX_EXECUTION_TIME(3600000) */ (SELECT SLEEP(0.5)) AS true_if_subquery_is_timedout;
|
|
|
|
--echo #
|
|
--echo # 6. Test max_execution_time with prepared statements.
|
|
--echo #
|
|
PREPARE stmt1 FROM "SELECT *, SLEEP(0.5) FROM t1 WHERE b= 'new_string'";
|
|
PREPARE stmt2 FROM "SELECT /*+ MAX_EXECUTION_TIME(2) */ *, SLEEP(0.5) FROM t1 WHERE b= 'new_string'";
|
|
PREPARE stmt3 FROM "SELECT /*+ MAX_EXECUTION_TIME(3600000) */ count(*) FROM t1";
|
|
|
|
# Following EXECUTE stmt1 should timeout.
|
|
--error ER_QUERY_TIMEOUT
|
|
EXECUTE stmt1;
|
|
|
|
# Following EXECUTE stmt2 should timeout.
|
|
--error ER_QUERY_TIMEOUT
|
|
EXECUTE stmt2;
|
|
|
|
# Following EXECUTE stmt2 should not timeout.
|
|
EXECUTE stmt3;
|
|
DEALLOCATE PREPARE stmt1;
|
|
DEALLOCATE PREPARE stmt2;
|
|
DEALLOCATE PREPARE stmt3;
|
|
|
|
--echo #
|
|
--echo # 7. Test max_execution_time with Stored Routines.
|
|
--echo #
|
|
# Case 7.1: Stored functions.
|
|
# Execution time limit applies to only top-level select statement.
|
|
#
|
|
DELIMITER |;
|
|
|
|
# Specifying MAX_EXECUTION_TIME for SELECTs of stored function is ignored.
|
|
CREATE FUNCTION f1() RETURNS INT
|
|
BEGIN
|
|
SELECT /*+ MAX_EXECUTION_TIME(1) */ SLEEP(1.5) INTO @a;
|
|
RETURN 1;
|
|
END|
|
|
DROP FUNCTION f1|
|
|
|
|
CREATE FUNCTION f1() RETURNS INT
|
|
BEGIN
|
|
SELECT SLEEP(3) INTO @a;
|
|
RETURN 1;
|
|
END|
|
|
|
|
CREATE FUNCTION f2() RETURNS INT
|
|
BEGIN
|
|
INSERT INTO t2 SELECT * FROM t2;
|
|
RETURN 1;
|
|
END|
|
|
|
|
DELIMITER ;|
|
|
|
|
INSERT INTO t2 VALUES (1, 'string1', 'string2');
|
|
|
|
# Set Session max_execution_time to 2 millisecond
|
|
SET @@SESSION.max_execution_time= 2;
|
|
# Following SELECT should timeout as max_execution_time is set for top level select now.
|
|
--error ER_QUERY_TIMEOUT
|
|
SELECT f1();
|
|
|
|
# Following SELECT should not time out as it is not a read only query. Note,
|
|
# for desabling timer is generated for this query.
|
|
SELECT /*+ MAX_EXECUTION_TIME(60000) */ f2();
|
|
|
|
DROP FUNCTION f1;
|
|
DROP FUNCTION f2;
|
|
|
|
# Case 7.2: Stored Procedure.
|
|
# Execution time limit is not applicable to Stored procedure.
|
|
DELIMITER |;
|
|
|
|
# Specifying MAX_EXECUTION_TIME for SELECTs of stored procedure is ignored.
|
|
CREATE PROCEDURE p1()
|
|
BEGIN
|
|
SELECT /*+ MAX_EXECUTION_TIME(1) */ SLEEP(1.5);
|
|
INSERT INTO t2 SELECT DISTINCT * FROM t2;
|
|
END|
|
|
DROP PROCEDURE p1|
|
|
|
|
CREATE PROCEDURE p1()
|
|
BEGIN
|
|
INSERT INTO t2 SELECT DISTINCT * FROM t2;
|
|
SELECT SLEEP(3);
|
|
END|
|
|
|
|
DELIMITER ;|
|
|
|
|
# max_execution_time is not applicable to Stored procedure.
|
|
CALL p1();
|
|
|
|
DROP PROCEDURE p1;
|
|
DROP TABLE t2;
|
|
|
|
# Case 7.3: Events.
|
|
# Execution time limit is not applicable to SELECTs of events.
|
|
SET @global_event_scheduler_status= @@global.event_scheduler;
|
|
SET @@global.event_scheduler= ON;
|
|
SET @@global.max_execution_time= 1000;
|
|
CREATE TABLE t2 (f1 int, f2 int);
|
|
|
|
# Both of the following selects are interrupted because of timeout.
|
|
SELECT SLEEP(5) into @a;
|
|
SELECT @a;
|
|
|
|
delimiter |;
|
|
|
|
# Specifying MAX_EXECUTION_TIME for SELECTs of events is ignored.
|
|
CREATE EVENT event1 ON SCHEDULE AT CURRENT_TIMESTAMP
|
|
DO BEGIN
|
|
SELECT SLEEP(2) into @a;
|
|
SELECT /*+ MAX_EXECUTION_TIME(1) */ SLEEP(2) into @b;
|
|
INSERT INTO t2 VALUES(@a, @b);
|
|
END|
|
|
|
|
delimiter ;|
|
|
|
|
--echo # Wait until at least one instance of event is executed.
|
|
let $wait_condition= SELECT /*+ MAX_EXECUTION_TIME(3600000) */ COUNT(*) FROM t2;
|
|
--source include/wait_condition.inc
|
|
|
|
#Since MAX_EXECUTION_TIME is not applicable for events & SELECTs of event,
|
|
#selects of event1 are not interruped so table contains two 0 values.
|
|
SELECT /*+ MAX_EXECUTION_TIME(3600000) */ * FROM t2;
|
|
|
|
DELETE FROM t2;
|
|
SET @@global.event_scheduler= @global_event_scheduler_status;
|
|
SET @@global.max_execution_time= 0;
|
|
|
|
# Case 7.4: Triggers
|
|
# Execution time limit is not applicable to SELECTs of triggers.
|
|
delimiter |;
|
|
|
|
CREATE TABLE t3 (f1 int)|
|
|
|
|
# Specifying MAX_EXECUTION_TIME for SELECTs of events is ignored.
|
|
CREATE TRIGGER t1_before_trigger BEFORE INSERT ON t1 FOR EACH ROW
|
|
BEGIN
|
|
SELECT SLEEP(2) into @a;
|
|
SELECT /*+ MAX_EXECUTION_TIME(1) */ SLEEP(2) into @b;
|
|
INSERT INTO t3 VALUES(@a);
|
|
INSERT INTO t3 VALUES(@b);
|
|
END|
|
|
DROP TRIGGER t1_before_trigger|
|
|
|
|
CREATE TRIGGER t1_before_trigger BEFORE INSERT ON t1 FOR EACH ROW
|
|
BEGIN
|
|
SELECT SLEEP(2) into @a;
|
|
INSERT INTO t3 VALUES(@a);
|
|
END
|
|
|
|
|
|
|
delimiter ;|
|
|
|
|
# Both of the following selects are interrupted because of timeout.
|
|
SELECT SLEEP(5) into @a;
|
|
SELECT /*+ MAX_EXECUTION_TIME(1000) */ SLEEP(2) into @b;
|
|
SELECT @a, @b;
|
|
|
|
INSERT INTO t1 VALUES (1, 'string');
|
|
#Since MAX_EXECUTION_TIME is not applicable for SELECTs of triggers, selects of
|
|
#triggers are not interruped so table contains 0 value.
|
|
SELECT /*+ MAX_EXECUTION_TIME(3600000) */ * FROM t3;
|
|
|
|
DROP TABLE t1,t2,t3;
|
|
|
|
--echo #
|
|
--echo # 8. Test MAX_EXECUTION_TIME precedence set at different levels.
|
|
--echo #
|
|
|
|
# Session MAX_EXECUTION_TIME is used when statament level MAX_EXECUTION_TIME
|
|
# value is not set.
|
|
SET @@SESSION.max_execution_time= 1000;
|
|
SELECT sleep(5);
|
|
|
|
# Statement level MAX_EXECUTION_TIME takes precedence over session level
|
|
# MAX_EXECUTION_TIME.
|
|
SELECT /*+ MAX_EXECUTION_TIME(20000) */ sleep(5);
|
|
|
|
SET @@SESSION.max_execution_time= 0;
|
|
|
|
--echo #
|
|
--echo # 9. MAX_EXECUTION_TIME status variables.
|
|
--echo #
|
|
|
|
# Case 9.1 Check MAX_EXECUTION_TIME_SET and MAX_EXECUTION_TIME_EXCEEDED status.
|
|
--disable_warnings
|
|
SELECT CONVERT(VARIABLE_VALUE, UNSIGNED) INTO @time_set
|
|
FROM performance_schema.global_status
|
|
WHERE VARIABLE_NAME= 'MAX_EXECUTION_TIME_SET';
|
|
|
|
SELECT CONVERT(VARIABLE_VALUE, UNSIGNED) INTO @time_exceeded
|
|
FROM performance_schema.global_status
|
|
WHERE VARIABLE_NAME= 'MAX_EXECUTION_TIME_EXCEEDED';
|
|
--enable_warnings
|
|
|
|
SELECT /*+ MAX_EXECUTION_TIME(10) */ SLEEP(1);
|
|
|
|
--echo # Ensure that the counters for:
|
|
--echo # - statements that are time limited; and
|
|
--echo # - statements that exceeded their maximum execution time
|
|
--echo # are incremented.
|
|
|
|
--disable_warnings
|
|
SELECT 1 AS STATUS FROM performance_schema.global_status
|
|
WHERE VARIABLE_NAME= 'MAX_EXECUTION_TIME_SET'
|
|
AND CONVERT(VARIABLE_VALUE, UNSIGNED) > @time_set;
|
|
|
|
SELECT 1 AS STATUS FROM performance_schema.global_status
|
|
WHERE VARIABLE_NAME= 'MAX_EXECUTION_TIME_EXCEEDED'
|
|
AND CONVERT(VARIABLE_VALUE, UNSIGNED) > @time_exceeded;
|
|
--enable_warnings
|
|
|
|
# Case 9.2 Check MAX_EXECUTION_TIME_FAILED status on timer creation failure.
|
|
connect(con1, localhost, root,,);
|
|
|
|
--disable_warnings
|
|
SELECT CONVERT(VARIABLE_VALUE, UNSIGNED) INTO @time_set_failed
|
|
FROM performance_schema.global_status
|
|
WHERE VARIABLE_NAME= 'MAX_EXECUTION_TIME_SET_FAILED';
|
|
--enable_warnings
|
|
|
|
SET DEBUG= '+d,thd_timer_create_failure';
|
|
SELECT /*+ MAX_EXECUTION_TIME(10) */ SLEEP(1);
|
|
SET DEBUG= '-d,thd_timer_create_failure';
|
|
|
|
--disable_warnings
|
|
SELECT 1 AS STATUS FROM performance_schema.global_status
|
|
WHERE VARIABLE_NAME= 'MAX_EXECUTION_TIME_SET_FAILED'
|
|
AND CONVERT(VARIABLE_VALUE, UNSIGNED) > @time_set_failed;
|
|
|
|
# Case 9.3 Check MAX_EXECUTION_TIME_FAILED status on timer set failure.
|
|
SELECT CONVERT(VARIABLE_VALUE, UNSIGNED) INTO @time_set_failed
|
|
FROM performance_schema.global_status
|
|
WHERE VARIABLE_NAME= 'MAX_EXECUTION_TIME_SET_FAILED';
|
|
|
|
SET DEBUG= '+d,thd_timer_set_failure';
|
|
SELECT /*+ MAX_EXECUTION_TIME(10) */ SLEEP(1);
|
|
SET DEBUG= '-d,thd_timer_set_failure';
|
|
|
|
SELECT 1 AS STATUS FROM performance_schema.global_status
|
|
WHERE VARIABLE_NAME= 'MAX_EXECUTION_TIME_SET_FAILED'
|
|
AND CONVERT(VARIABLE_VALUE, UNSIGNED) > @time_set_failed;
|
|
--enable_warnings
|
|
|
|
connection default;
|
|
disconnect con1;
|
|
|
|
SET @@SESSION.max_execution_time= 0;
|
|
# Check that all connections opened by test cases in this file are really gone
|
|
# so execution of other tests won't be affected by their presence.
|
|
--source include/wait_until_count_sessions.inc
|