sql >> Base de Datos >  >> RDS >> Mysql

Tiempo de espera de consulta global en MySQL 5.6

Parece que no hay equivalente a max_execution_time en MySQL antes de las versiones 5.7.4 y 5.7.8 (la configuración cambió de nombre). Lo que puede hacer es crear su propio trabajo periódico que verifique si las consultas han excedido el tiempo de espera y eliminarlas manualmente. Desafortunadamente, eso no es lo mismo que lo que hacen las versiones más nuevas de MySQL:sin inspeccionar la información del comando, terminará eliminando todas las consultas, no solo de lectura SELECT , y es casi imposible de controlar a nivel de sesión.

Una forma de hacerlo sería crear un procedimiento almacenado que consulta la lista de procesos y mata según sea necesario. Tal procedimiento almacenado podría verse así:

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 ;

Alternativamente, podría implementar todo eso en la lógica de su aplicación, pero requeriría viajes de ida y vuelta separados a la base de datos para eliminar cada consulta. Lo que queda entonces es llamar a esto periódicamente:

# Somewhere suitable
engine.execute(text("CALL stmt_timeout_killer(:timeout)"), timeout=30)

Cómo y dónde depende en gran medida de su aplicación real.