Troppe connessioni al database su Amazon RDS


9

Stiamo riscontrando problemi con gli utenti che eseguono query / visualizzazioni in Drupal che a volte causano il blocco del nostro sito. Il blocco si verifica perché la query provoca un numero di connessioni al database fino a 400+ e praticamente ogni volta che il sito supera 100 connessioni al database, il sito rallenta terribilmente e semplicemente non risponde.

Stiamo eseguendo Amazon RDS utilizzando MySQL Red Hat Linux

Abbiamo un EC2 abbastanza grande sul server delle applicazioni front-end e un RDS abbastanza grande.

Il modo in cui stiamo risolvendo questo problema ora è trovare la query offensiva e ucciderla. Una volta terminata la query ... le nostre connessioni al database scendono a circa 20, che è la quantità normale che si vede quando si monitorano le statistiche del sito.

C'è un modo per fermare la query offensiva e ucciderla prima che venga eseguita troppo a lungo e consumi le connessioni? Sto cercando di automatizzare l'uccisione della query non valida prima che accada, o almeno realizzare dopo 30 secondi che è una query non valida e ucciderla.


3
Uccidere la query tramite un processo automatizzato sembra un approccio completamente sbagliato ... se l'istanza RDS è in realtà sottodimensionata, causando l'accumulo iniziale ... o c'è qualcosa di sbagliato con la logica nella tua applicazione, sembra trovare il vero problema con la query sarebbe la cosa da fare ...
Michael - sqlbot

Puoi usare MONyog-MySQL Monitor che ha uno sniffer basato su PROCESSLIST che aiuta a notificare e uccidere le query di lunga durata. Funziona bene anche con Amazon RDS.
Peter Venderberghe,

Non essere un ragazzo MySql / Linux - come puoi avere più di 100 connessioni da un sito Web? Faccio solo asp.net e una qualsiasi delle mie pagine apre solo UNA connessione alla volta, quindi ciò significherebbe elaborare più di 100 pagine contemporaneamente (in realtà più di una pagina ha solo una connessione aperta mentre ne ha bisogno). Vorrei esaminare il tuo approccio alla gestione delle connessioni, che è seriamente inefficiente.
TomTom,

AWS imposta le connessioni massime in base alle dimensioni dell'istanza. la formula che usano è: max_connections = {DBInstanceClassMemory / 12582880} Consulta la documentazione relativa ai gruppi di parametri: https://console.aws.amazon.com/rds/home?region=us-east-1#parameter-groups:

Forse dovresti considerare di implementare una sorta di pool di connessioni.
Mustaccio,

Risposte:


6

Ecco una procedura memorizzata per eliminare i SELECT di lunga durata

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 $$

Per uccidere SELECTs che durano più di 30 secondi, esegui questo

CALL test.Kill_Long_Running_Selects(30,0);

Se vuoi vedere le connessioni che vengono uccise, esegui questo

CALL test.Kill_Long_Running_Selects(30,1);

Forse puoi creare un evento MySQL per chiamare questa stored procedure ogni minuto.

Se Amazon non ti consente di avere il privilegio EVENT , dovrai scrivere uno script shell esterno sul server EC2 per connetterti al DB ed eseguire la Stored Procedure. Lo script della shell può essere inserito in un crontab.

Se Amazon non ti consente di disporre dei privilegi PROCESS e SUPER , potrebbe essere necessario spostare il DB fuori da RDS e in un'altra istanza EC2 che esegue MySQL per farlo. È quindi possibile creare l'evento MySQL senza le restrizioni di hosting di Amazon.


1
Questa è un'ottima risposta! L'ho usato su RDS oggi semplicemente cambiando la linea KILL @kill_id; a "chiama mysql.rds_kill (@kill_id);" e funziona perfettamente.
Dave R,

@DaveR grazie. Aggiornerò quella linea più tardi oggi.
RolandoMySQLDBA,

@DaveR Ho appena fatto quel cambio di linea. Grazie per averlo segnalato.
RolandoMySQLDBA,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.