Amazon RDSのデータベース接続が多すぎる


9

Drupalでクエリ/ビューを実行しているユーザーに問題があり、サイトがフリーズすることがあります。フリーズが発生するのは、クエリによってデータベース接続の数が最大400以上になり、基本的にサイトが100を超えるデータベース接続を行うと、サイトの速度が大幅に低下し、応答しなくなるためです。

MySQL Red Hat Linuxを使用してAmazon RDSを実行しています

フロントエンドアプリサーバーには十分な大きさのEC2があり、十分な大きさのRDSがあります。

この問題を修正する方法は、問題のあるクエリを見つけて強制終了することです。クエリが強制終了されると、データベース接続は約20に低下します。これは、サイト統計を監視するときに表示される通常の量です。

問題のあるクエリを停止し、実行時間が長すぎて接続を消費する前にそれを強制終了する方法はありますか?不正なクエリが発生する前に強制終了することを自動化するか、少なくとも30秒後に不正なクエリを認識して強制終了します。


3
自動化されたプロセスを介してクエリを強制終了すると、完全に間違ったアプローチのように見えます... RDSインスタンスが実際に能力不足で、初期のパイルアップを引き起こしているかどうか、またはアプリケーションのロジックに何か問題がある場合、実際の問題を見つけるようですクエリを使用して行うことになります...
マイケル-sqlbot

PROCESSLISTベースのスニファーを備えたMONyog -MySQLモニターを使用すると、長時間実行されているクエリの通知と強制終了に役立ちます。Amazon RDSでもうまく機能します。
Peter Venderberghe 2013

MySql / Linuxの男ではない-1つのWebサイトから100以上の接続を確立するにはどうすればよいですか?私はasp.netのみを実行しており、どのページも一度に1つの接続しか開かないため、同時に100以上のページを処理することになります(実際には、必要なときに開いている接続のみがページにあるため)。私は接続を処理するあなたのアプローチを調べます-それは非常に非効率的です。
TomTom 2013

AWSは、インスタンスのサイズに基づいて最大接続数を設定します。それらが使用する式は次のとおりです。max_connections = {DBInstanceClassMemory / 12582880}パラメータグループのドキュメントを参照してください:https:

ある種の接続プーリングの実装を検討する必要があるかもしれません。
mustaccio 2014

回答:


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

30秒より長く実行しているSELECTを強制終了するには、これを実行します

CALL test.Kill_Long_Running_Selects(30,0);

強制終了されている接続を確認する場合は、これを実行します

CALL test.Kill_Long_Running_Selects(30,1);

おそらく、このストアドプロシージャを毎分呼び出すMySQLイベントを作成できます。

AmazonがEVENT権限を許可しない場合は、EC2サーバーで外部シェルスクリプトを作成してDBに接続し、ストアドプロシージャを実行する必要があります。そのシェルスクリプトはcrontabに入れることができます。

AmazonでPROCESSおよびSUPER権限を許可されていない場合、DBをRDSからMySQLを実行している別のEC2インスタンスに移動して、これを実行する必要がある場合があります。その後、Amazonのホスティング制限なしでMySQLイベントを作成できます。


1
これは素晴らしい答えです!今日、KILL @kill_idという行を変更するだけで、RDSで使用しました。「mysql.rds_kill(@kill_id);を呼び出す」そしてそれは完全に動作します。
Dave R

@DaveRありがとうございます。今日は後でその行を更新します。
RolandoMySQLDBA 2017

@DaveRその行を変更しました。これを指摘してくれてありがとう。
RolandoMySQLDBA 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.