Demasiadas conexiones de bases de datos en Amazon RDS

9

Tenemos problemas con los usuarios que ejecutan consultas / vistas en Drupal que ocasionalmente hacen que nuestro sitio se congele. La congelación se produce porque la consulta hace que el número de conexiones de la base de datos aumente a más de 400 y, básicamente, cada vez que el sitio supera las 100 conexiones de la base de datos, el sitio se ralentiza terriblemente y simplemente no responde.

Estamos ejecutando Amazon RDS usando MySQL Red Hat Linux

Tenemos un EC2 lo suficientemente grande en el servidor de aplicaciones front-end y un RDS lo suficientemente grande.

La forma en que estamos solucionando este problema ahora es encontrar la consulta ofensiva y eliminarla. Una vez que se finaliza la consulta ... nuestras conexiones de base de datos caen a alrededor de 20, que es la cantidad normal que se ve al monitorear las estadísticas del sitio.

¿Hay alguna manera de detener la consulta ofensiva y eliminarla antes de que se ejecute demasiado tiempo y consuma las conexiones? Estoy tratando de automatizar la eliminación de la consulta incorrecta antes de que ocurra, o al menos me doy cuenta después de 30 segundos de que es una consulta incorrecta y la elimino.

Preocupado
fuente
3
Matar la consulta a través de un proceso automatizado parece un enfoque completamente incorrecto ... si su instancia de RDS tiene poca potencia, lo que provoca el apilamiento inicial ... o hay algo mal con la lógica en su aplicación, parece encontrar el problema real con la consulta sería lo que hay que hacer ...
Michael - sqlbot
Puede usar MONyog-MySQL Monitor, que tiene un sniffer basado en PROCESSLIST que ayuda a notificar y MATAR consultas de larga duración. Funciona bien con Amazon RDS también.
Peter Venderberghe
No ser un tipo MySql / Linux: ¿cómo puede tener más de 100 conexiones desde un sitio web? Solo hago asp.net, y cualquiera de mis páginas solo abre UNA conexión a la vez, lo que significaría procesar más de 100 páginas al mismo tiempo (en realidad, más que una página solo tiene una conexión abierta mientras la necesita). Analizaría su enfoque de manejar las conexiones, eso es muy ineficiente.
TomTom
AWS establece las conexiones máximas en función del tamaño de su instancia. la fórmula que usan es: max_connections = {DBInstanceClassMemory / 12582880} Consulte la documentación de Grupos de parámetros: https://console.aws.amazon.com/rds/home?region=us-east-1#parameter-groups:
Puede ser que deba considerar implementar algún tipo de agrupación de conexiones.
mustaccio

Respuestas:

6

Aquí hay un procedimiento almacenado para matar SELECTs de larga ejecución

DELIMITER $$

DROP PROCEDURE IF EXISTS `test`.`Kill_Long_Running_Selects` $$
CREATE PROCEDURE `test`.`Kill_Long_Running_Selects` (time_limit INT,display INT)
BEGIN

    DECLARE ndx,lastndx INT;

    DROP TABLE IF EXISTS test.LongRunningSelects;
    CREATE TABLE test.LongRunningSelects
    (
        id INT NOT NULL AUTO_INCREMENT,
        idtokill BIGINT,
        PRIMARY KEY (id)
    ) ENGINE=MEMORY;
    INSERT INTO test.LongRunningSelects (idtokill)
    SELECT id FROM information_schema.processlist
    WHERE user<>'system user' AND info regexp '^SELECT' AND time > time_limit;

    SELECT COUNT(1) INTO lastndx FROM test.LongRunningSelects;
    SET ndx = 0;
    WHILE ndx < lastndx DO
        SET ndx = ndx + 1;
        SELECT idtokill INTO @kill_id
        FROM test.LongRunningSelects WHERE id = ndx;
        CALL mysql.rds_kill(@kill_id);
    END WHILE;

    IF lastndx > 0 THEN
        IF display = 1 THEN
            SELECT GROUP_CONCAT(idtokill) INTO @idlist FROM test.LongRunningSelects;
            SELECT @idlist IDs_KIlled;
            SELECT CONCAT('Processes Killed : ',lastndx) Kill_Long_Running_Selects;
        END IF;
    END IF;

END $$

Para eliminar SELECTs que se ejecutan por más de 30 segundos, ejecute esto

CALL test.Kill_Long_Running_Selects(30,0);

Si desea ver que se corten las conexiones, ejecute esto

CALL test.Kill_Long_Running_Selects(30,1);

Quizás pueda crear un evento MySQL para llamar a este Procedimiento almacenado cada minuto.

Si Amazon no le permite tener el privilegio EVENT , deberá escribir un script de shell externo en el servidor EC2 para conectarse a la base de datos y ejecutar el Procedimiento almacenado. Ese script de shell se puede poner en un crontab.

Si Amazon no le permite tener los privilegios de PROCESO y SUPER , es posible que deba mover la base de datos fuera de RDS a otra instancia de EC2 que ejecute MySQL para lograr esto. Luego, podría crear el evento MySQL sin las restricciones de alojamiento de Amazon.

RolandoMySQLDBA
fuente
1
¡Esta es una respuesta genial! Lo usé en RDS hoy simplemente cambiando la línea KILL @kill_id; para "llamar a mysql.rds_kill (@kill_id);" Y funciona perfectamente.
Dave R
@DaveR gracias. Actualizaré esa línea más tarde hoy.
RolandoMySQLDBA
@DaveR Acabo de hacer ese cambio de línea. Gracias por señalar esto.
RolandoMySQLDBA