MySQL 5.6中的全局查询超时

时间:2019-01-02 11:24:21

标签: python mysql python-2.7 sqlalchemy mysql-python

我需要在我的应用程序中全局应用查询超时。查询:SET SESSION max_execution_time=1在MySQL 5.7中完成。我正在使用MySQL 5.6,目前无法升级。使用SQL Alchemy的任何解决方案也将有所帮助。

1 个答案:

答案 0 :(得分:3)

在版本5.7.4和5.7.8之前的MySQL中,从

It seems there is no equivalentmax_execution_time(设置更改了名称)。您可以做的是创建自己的定期作业,以检查查询是否已超过超时并手动终止它们。不幸的是,这与更新的MySQL版本并不完全相同:如果不检查命令信息,最终将杀死所有查询,而不仅仅是读SELECT,并且几乎不可能在会话级别进行控制。

一种实现方法是创建一个stored procedure,该process list根据需要查询killsAngular。这样的存储过程可能看起来像:

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)

如何以及在何处完全取决于您的实际应用。