Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Tempo limite de consulta global no MySQL 5.6


Parece que não há equivalente para max_execution_time no MySQL antes das versões 5.7.4 e 5.7.8 (a configuração mudou seu nome). O que você pode fazer é criar seu próprio trabalho periódico que verifica se as consultas excederam o tempo limite e eliminá-las manualmente. Infelizmente, isso não é exatamente o mesmo que as versões mais recentes do MySQL fazem:sem inspecionar as informações do comando, você acabará matando todas as consultas, não apenas lendo apenas SELECT , e é quase impossível controlar no nível da sessão.

Uma maneira de fazer isso seria criar um procedimento armazenado que consulta a lista de processos e matar como requerido. Esse procedimento armazenado pode se parecer com:
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 ;

Como alternativa, você pode implementar tudo isso na lógica do aplicativo, mas exigiria viagens de ida e volta separadas para o banco de dados para que cada consulta fosse eliminada. O que resta então é chamar isso periodicamente:
# Somewhere suitable
engine.execute(text("CALL stmt_timeout_killer(:timeout)"), timeout=30)

Como e onde exatamente depende muito da sua aplicação real.