Слишком много подключений к базам данных в Amazon RDS

9

У нас возникают проблемы с пользователями, выполняющими запросы / просмотры в Drupal, которые иногда приводят к зависанию нашего сайта. Замораживание происходит из-за того, что запрос приводит к тому, что число подключений к базе данных увеличивается до 400+, и в основном каждый раз, когда сайт переходит более 100 подключений к базе данных, сайт ужасно замедляется и просто не отвечает.

Мы запускаем Amazon RDS, используя MySQL Red Hat Linux

У нас достаточно большой EC2 на сервере приложений и достаточно большой RDS.

Теперь мы решаем эту проблему, чтобы найти ошибочный запрос и убить его. Как только запрос убит ... количество подключений к нашей базе данных падает до 20, что является нормальным показателем, который вы видите при мониторинге статистики сайта.

Есть ли способ остановить ошибочный запрос и завершить его до того, как он запустится слишком долго и использует соединения? Я пытаюсь автоматизировать уничтожение плохого запроса до того, как это произойдет, или, по крайней мере, через 30 секунд понять, что это плохой запрос, и уничтожить его.

ConcernedCEO
источник
3
Уничтожение запроса с помощью автоматизированного процесса кажется совершенно неправильным подходом ... если ваш экземпляр RDS на самом деле недостаточно силен, что вызывает начальный сбой ... или что-то не так с логикой в ​​вашем приложении, похоже, что найти реальную проблему с запросом было бы то, что нужно сделать ...
Майкл - sqlbot
Вы можете использовать MONyog - MySQL Monitor, в котором есть сниффер, основанный на PROCESSLIST, для оповещения и уничтожения длительных запросов. Это хорошо работает с Amazon RDS тоже.
Питер Вендерберге
Не будучи парнем MySql / Linux - как вы можете иметь более 100 соединений с одного сайта? Я делаю только asp.net, и любая из моих страниц открывает только ОДНО соединение за раз - так что это будет означать обработку более 100 страниц одновременно (на самом деле больше, поскольку страница имеет только открытое соединение, когда оно необходимо). Я хотел бы рассмотреть ваш подход к обработке соединений - это серьезно неэффективно.
TomTom
AWS устанавливает максимальное количество подключений в зависимости от размера вашего экземпляра. формула, которую они используют: max_connections = {DBInstanceClassMemory / 12582880} См. документацию групп параметров: https://console.aws.amazon.com/rds/home?region=us-east-1#parameter-groups:
Может быть, вы должны рассмотреть возможность реализации какого-либо пула соединений.
Мустаччо

Ответы:

6

Вот хранимая процедура, чтобы убить долго работающие SELECT

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

Чтобы убить SELECTs, работающие дольше 30 секунд, вы запускаете эту

CALL test.Kill_Long_Running_Selects(30,0);

Если вы хотите увидеть разрыв соединений, запустите

CALL test.Kill_Long_Running_Selects(30,1);

Возможно, вы можете создать событие MySQL для вызова этой хранимой процедуры каждую минуту.

Если Amazon не позволяет вам иметь привилегию EVENT , вам придется написать сценарий внешней оболочки на сервере EC2, чтобы подключиться к БД и запустить хранимую процедуру. Этот сценарий оболочки может быть помещен в crontab.

Если Amazon не позволяет вам иметь привилегии PROCESS и SUPER , вам может потребоваться переместить БД из RDS в другой экземпляр EC2, на котором выполняется MySQL, для этого. Затем вы можете создать событие MySQL без ограничений хостинга Amazon.

RolandoMySQLDBA
источник
1
Это отличный ответ! Сегодня я использовал его в RDS, просто изменив строку KILL @kill_id; "вызвать mysql.rds_kill (@kill_id);" и работает отлично.
Дэйв Р
@DaveR спасибо. Я обновлю эту строку позже сегодня.
RolandoMySQLDBA
@DaveR Я только что изменил эту строку. Спасибо за указание на это.
RolandoMySQLDBA