Zdá se, že neexistuje žádný ekvivalent
na max_execution_time
v MySQL před verzemi 5.7.4 a 5.7.8 (nastavení změnilo svůj název). Co můžete udělat, je vytvořit si vlastní pravidelnou úlohu, která kontroluje, zda dotazy nepřekročily časový limit, a ručně je zabíjet. Bohužel to není úplně stejné jako to, co dělají novější verze MySQL:bez kontroly informací o příkazu skončíte tím, že zabijete všechny dotazy, nejen pouze čtení SELECT
a je téměř nemožné jej ovládat na úrovni relace.
Jedním ze způsobů, jak toho dosáhnout, by bylo vytvořit uloženou proceduru který se dotazuje na seznam procesů a zabíjí podle potřeby. Takto uložená procedura může vypadat takto:
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 ;
Alternativně byste to všechno mohli implementovat do své aplikační logiky, ale vyžadovalo by to samostatné zpáteční cesty do databáze pro každý dotaz, který má být zrušen. Zbývá tedy toto periodicky volat:
# Somewhere suitable
engine.execute(text("CALL stmt_timeout_killer(:timeout)"), timeout=30)
Jak a kde přesně závisí na vaší skutečné aplikaci.