Отправить заявку

MySQL: автоматическое завершение долгих запросов

Наверное у каждого бывают запросы, которые выполняются долго или очень долго. Конечно - если это Ваш сервер и Ваши запросы - то это одно дело, но если сервер Ваш а запросы нет :) то, возможно, Вам понадобиться убивать такие "висячие" запросы.

Данный способ позволяет отслеживать и завершать все запросы которые длятся больше заданного количества секунд.
Процедура `mysql_kill_query` убивает все запросы, за исключением запущенных с правами супер пользователя, время выполнения которых превышает runtime секунд.

Данный метод работает начиная с версии MySQL 5.1

DELIMITER //
CREATE PROCEDURE `mysql_kill_query` ( IN runtime TINYINT UNSIGNED )
LANGUAGE SQL
NOT DETERMINISTIC
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE connid INT UNSIGNED;
DECLARE cur1 CURSOR FOR SELECT ID FROM information_schema.PROCESSLIST
WHERE CONCAT ("'", USER, "'@'", SUBSTRING_INDEX(HOST,':',1), "'") IN
( SELECT `USER_PRIVILEGES`.`GRANTEE` AS `GRANTEE` FROM `information_schema`.`USER_PRIVILEGES`
WHERE NOT(`USER_PRIVILEGES`.`GRANTEE` IN
(SELECT GRANTEE FROM `information_schema`.`USER_PRIVILEGES`
WHERE `USER_PRIVILEGES`.`PRIVILEGE_TYPE` = 'SUPER' GROUP BY `USER_PRIVILEGES`.`GRANTEE`)))
AND COMMAND ='Query'
AND TIME>= runtime;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; 
OPEN cur1;
REPEAT
FETCH cur1 INTO connid;
IF NOT done THEN
KILL connid;
END IF;
UNTIL done END REPEAT;
CLOSE cur1;
END//
DELIMITER ;

Теперь нам необходимо добавить в cron выполнение нашей функции каждые две N секунды (в нашем примере это 2 секунды) с максимальным временем запроса в две секунды:

SET GLOBAL event_scheduler=ON;
 CREATE EVENT IF NOT EXISTS `mysql_kill_query`
ON SCHEDULE EVERY 2 SECOND
ON COMPLETION PRESERVE ENABLE
DO CALL mysql_kill_query(2);
Другие публикации