MySQL 5.6中的全局查询超时

Swa*_*nha 8 python mysql sqlalchemy mysql-python python-2.7

我需要在我的应用程序中在全局级别应用查询超时.查询:SET SESSION max_execution_time=1使用MySQL 5.7执行此操作.我使用的是MySQL 5.6,目前无法升级.使用SQL Alchemy的任何解决方案也会有所帮助.

Ilj*_*ilä 7

这似乎是没有等同max_execution_time5.7.4和5.7.8之前的版本在MySQL(设置更名)。您可以做的是创建自己的定期作业,检查查询是否超过超时并手动终止它们。不幸的是,这与较新的 MySQL 版本所做的并不完全相同:如果不检查命令信息,您最终将终止所有查询,而不仅仅是 read only 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 ;
Run Code Online (Sandbox Code Playgroud)

或者,您可以在应用程序逻辑中实现所有这些,但是对于要终止的每个查询,它需要单独往返数据库。剩下的就是定期调用它:

# Somewhere suitable
engine.execute(text("CALL stmt_timeout_killer(:timeout)"), timeout=30)
Run Code Online (Sandbox Code Playgroud)

如何以及在哪里完全取决于您的实际应用程序。