it-swarm.com.de

Zu viele Datenbankverbindungen auf Amazon RDS

Wir haben Probleme mit Benutzern, die Abfragen/Ansichten in Drupal) ausführen, die gelegentlich zum Einfrieren unserer Website führen. Das Einfrieren tritt auf, weil durch die Abfrage die Anzahl der Datenbankverbindungen auf 400+ und grundsätzlich jederzeit erhöht wird Die Site geht über 100 Datenbankverbindungen. Die Site verlangsamt sich schrecklich und reagiert einfach nicht.

Wir führen Amazon RDS mit MySQL Red Hat Linux aus

Wir haben eine ausreichend große EC2 auf dem Front-End-App-Server und eine ausreichend große RDS.

Wir beheben dieses Problem jetzt, indem wir die fehlerhafte Abfrage finden und beenden. Sobald die Abfrage beendet ist ... fallen unsere Datenbankverbindungen auf etwa 20, was der normale Betrag ist, den Sie bei der Überwachung der Site-Statistiken sehen.

Gibt es eine Möglichkeit, die fehlerhafte Abfrage zu stoppen und zu beenden, bevor sie zu lange ausgeführt wird und die Verbindungen verbraucht? Ich versuche, das Beenden der fehlerhaften Abfrage zu automatisieren, bevor sie auftritt, oder zumindest nach 30 Sekunden zu erkennen, dass es sich um eine fehlerhafte Abfrage handelt, und sie zu beenden.

9
ConcernedCEO

Hier ist eine gespeicherte Prozedur zum Beenden von SELECTs mit langer Laufzeit

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

Um SELECTs zu beenden, die länger als 30 Sekunden laufen, führen Sie dies aus

CALL test.Kill_Long_Running_Selects(30,0);

Wenn Sie sehen möchten, dass die Verbindungen unterbrochen werden, führen Sie dies aus

CALL test.Kill_Long_Running_Selects(30,1);

Vielleicht können Sie ein MySQL-Ereignis erstellen, um diese gespeicherte Prozedur jede Minute aufzurufen.

Wenn Amazon Ihnen nicht die Berechtigung EVENT gewährt, müssen Sie ein externes Shell-Skript auf den EC2-Server schreiben, um eine Verbindung zur Datenbank herzustellen und den gespeicherten auszuführen Verfahren. Dieses Shell-Skript kann in eine Crontab eingefügt werden.

Wenn Amazon Ihnen nicht die Berechtigungen PROCESS und SUPER gewährt, benötigen Sie möglicherweise um die Datenbank aus RDS in eine andere EC2-Instanz zu verschieben, auf der MySQL ausgeführt wird, um dies zu erreichen. Sie können das MySQL-Ereignis dann ohne die Hosting-Einschränkungen von Amazon erstellen.

6
RolandoMySQLDBA