Похоже, в MySQL до версий 5.7.4 и 5.7.8 нет эквивалента - max_execution_time
(параметр изменил свое имя).Что вы можете сделать, это создать свою собственную периодическую работу, которая проверяет, превысил ли время ожидания запросы, и вручную убивает их.К сожалению, это не совсем то же, что и в более новых версиях MySQL: без проверки информации о команде вы в конечном итоге убьете все запросы, а не просто прочитаете только SELECT
, и практически невозможно управлять на уровне сеанса.
Один из способов сделать это - создать хранимую процедуру , которая запрашивает список процессов и убивает по мере необходимости.Такая хранимая процедура может выглядеть следующим образом:
DELIMITER //
CREATE PROCEDURE stmt_timeout_killer (timeout INT)
BEGIN
DECLARE query_id INT;
DECLARE done INT DEFAULT FALSE;
DECLARE curs CURSOR FOR
SELECT id
FROM information_schema.processlist
WHERE command = 'Query' AND time >= timeout;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
-- Ignore ER_NO_SUCH_THREAD, in case the query finished between
-- checking the process list and actually killing threads
DECLARE CONTINUE HANDLER FOR 1094 BEGIN END;
OPEN curs;
read_loop: LOOP
FETCH curs INTO query_id;
IF done THEN
LEAVE read_loop;
END IF;
-- Prevent suicide
IF query_id != CONNECTION_ID() THEN
KILL QUERY query_id;
END IF;
END LOOP;
CLOSE curs;
END//
DELIMITER ;
В качестве альтернативы вы можете реализовать все это в логике своего приложения, но для этого потребуется отдельное обратное обращение к базе данных для каждого запроса, подлежащего уничтожению.Остается периодически вызывать этот код:
# Somewhere suitable
engine.execute(text("CALL stmt_timeout_killer(:timeout)"), timeout=30)
Как и где именно сильно зависит от вашего фактического заявления.