Terlalu banyak koneksi basis data di Amazon RDS

9

Kami mengalami masalah dengan pengguna yang menjalankan kueri / tampilan di Drupal yang terkadang menyebabkan situs kami membeku. Pembekuan terjadi karena permintaan menyebabkan jumlah koneksi basis data naik hingga 400+ dan pada dasarnya kapan saja situs berjalan lebih dari 100 koneksi basis data situs melambat sangat dan hanya tidak merespon.

Kami menjalankan Amazon RDS menggunakan MySQL Red Hat Linux

Kami memiliki EC2 yang cukup besar di server aplikasi ujung depan, dan RDS yang cukup besar.

Cara kami memperbaiki masalah ini sekarang adalah dengan menemukan kueri yang menyinggung, dan membunuhnya. Setelah kueri terbunuh ... koneksi basis data kami turun menjadi sekitar 20 yang merupakan jumlah normal yang Anda lihat saat memantau statistik situs.

Apakah ada cara untuk menghentikan permintaan yang menyinggung dan membunuhnya sebelum berjalan terlalu lama dan menghabiskan koneksi? Saya mencoba untuk mengotomatiskan pembunuhan permintaan buruk sebelum itu terjadi, atau setidaknya menyadari setelah 30 detik itu permintaan yang buruk dan membunuhnya.

ConcernedCEO
sumber
3
Membunuh permintaan melalui proses otomatis sepertinya sepenuhnya pendekatan yang salah ... apakah contoh RDS Anda sebenarnya kurang bertenaga, menyebabkan pileup awal ... atau ada yang salah dengan logika di aplikasi Anda, sepertinya menemukan masalah yang sebenarnya dengan permintaan akan menjadi hal yang harus dilakukan ...
Michael - sqlbot
Anda dapat menggunakan MONyog-MySQL Monitor yang memiliki sniffer berbasis PROCESSLIST membantu dalam Memberitahu dan MEMBUNUH pertanyaan yang sudah berjalan lama. Ini berfungsi baik dengan Amazon RDS juga.
Peter Venderberghe
Bukan menjadi orang MySql / Linux - bagaimana Anda bisa memiliki 100+ koneksi dari satu situs web? Saya hanya menggunakan asp.net, dan halaman mana saja saya hanya membuka SATU koneksi pada satu waktu - sehingga itu berarti memproses 100+ halaman pada saat yang sama (sebenarnya lebih sebagai halaman hanya memiliki koneksi terbuka saat membutuhkannya). Saya akan melihat pendekatan Anda dalam menangani koneksi - yang sangat tidak efisien.
TomTom
AWS menetapkan koneksi maks berdasarkan ukuran instance Anda. rumus yang mereka gunakan adalah: max_connections = {DBInstanceClassMemory / 12582880} Lihat dokumentasi Grup Parameter: https://console.aws.amazon.com/rds/home?region=us-east-1#parameter-groups:
Mungkin Anda harus mempertimbangkan menerapkan semacam pooling koneksi.
mustaccio

Jawaban:

6

Berikut adalah Prosedur Tersimpan untuk membunuh SELECT yang sudah berjalan lama

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

Untuk membunuh SELECT berjalan lebih dari 30 detik, Anda menjalankan ini

CALL test.Kill_Long_Running_Selects(30,0);

Jika Anda ingin melihat koneksi mati, Anda menjalankan ini

CALL test.Kill_Long_Running_Selects(30,1);

Mungkin Anda dapat membuat Acara MySQL untuk memanggil Prosedur Tersimpan ini setiap menit.

Jika Amazon tidak membiarkan Anda memiliki hak istimewa ACARA , Anda harus menulis skrip shell eksternal pada server EC2 untuk terhubung ke DB dan menjalankan Prosedur Tersimpan. Script shell itu bisa dimasukkan ke dalam crontab.

Jika Amazon tidak membiarkan Anda memiliki hak istimewa PROSES dan SUPER , Anda mungkin perlu memindahkan DB dari RDS dan ke mesin EC2 lain yang menjalankan MySQL untuk melakukannya. Anda kemudian dapat membuat Acara MySQL tanpa batasan hosting Amazon.

RolandoMySQLDBA
sumber
1
Ini jawaban yang bagus! Saya menggunakannya pada RDS hari ini dengan hanya mengubah baris KILL @kill_id; untuk "memanggil mysql.rds_kill (@kill_id);" dan itu bekerja dengan sempurna.
Dave R
@DaveR terima kasih. Saya akan memperbarui baris itu hari ini.
RolandoMySQLDBA
@DaveR Saya baru saja membuat perubahan baris itu. Terima kasih telah menunjukkan ini.
RolandoMySQLDBA