Cara mengatasi terlalu banyak koneksi dan kesalahan fatal di mysql yang berjalan di vps

9

Saya menjalankan aplikasi PHPlist di server linode saya, secara bersamaan menjalankan 12 skrip PHP, yang masing-masing membuka koneksi MySQL. Sekarang ketika saya mengakses PHPlist sering menunjukkan kesalahan ini:

Kesalahan fatal: Maaf, server saat ini terlalu sibuk, silakan coba lagi nanti.

Ketika saya mencoba mengakses phpMyAdmin, itu menunjukkan saya kesalahan # 1040. Output dari skrip PHP saya yang dijalankan melalui cronpekerjaan menunjukkan:

Peringatan PHP: mysqli_connect (): (HY000 / 1040): Terlalu banyak koneksi

Saya menggunakan tumpukan LAMP di server dengan phpMyAdmin; yang topoutput dalam terminal menunjukkan mysqldmenggunakan 100-130% CPU. Ketika saya mencoba memecahkan masalah ini, saya mendapat beberapa petunjuk:

  • Tingkatkan variabel max_connection: Saya menggunakan 200 (100 secara default)
  • Open table cache: 512 (400 secara default)

Ada banyak variabel untuk diatur tetapi saya tidak dapat menentukan yang spesifik, saya mendapatkan beberapa referensi dari: terlalu banyak koneksi dan http://dev.mysql.com/doc/refman/5.5/en/table-cache. html

Tetapi menurut penggunaan saya bagaimana menambah memori dan berapa memori maksimum sulit bagi saya.

Di server saya, saya menggunakan sekitar 12 skrip PHP, aplikasi PHPlist untuk mengirim email, dan database utama untuk pendaftaran pengguna.

Mohon bantu saya untuk menyelesaikan masalah ini.

Shashank
sumber

Jawaban:

12

Pertama yang perlu Anda lakukan adalah menjalankan kueri ini:

SELECT user,host FROM mysql.user
WHERE super_priv='Y' AND
CONCAT(user,'@',host) <> 'root@localhost';

Ini akan mencantumkan semua pengguna yang memiliki hak SUPER . Sebagian besar pengguna yang melakukan pemrosesan DB terkait aplikasi tidak memerlukan hak istimewa ini. Menurut Dokumentasi MySQL , mereka yang memiliki hak SUPER dapat melakukan hal berikut:

  • Jalankan CHANGE MASTER TO untuk mengendalikan koordinat replikasi
  • BUNUH atau mysqladmin killuntuk membunuh utas milik akun lain
  • PURGE BINARY LOGS untuk secara sistematis menghapus log biner
  • Buat perubahan konfigurasi menggunakan SET GLOBAL untuk memodifikasi variabel sistem global
  • perintah debug mysqladmin
  • mengaktifkan atau menonaktifkan logging
  • melakukan pembaruan bahkan jika * read_only * variabel sistem diaktifkan
  • memulai dan menghentikan replikasi pada server slave
  • spesifikasi setiap akun dalam atribut DEFINER dari program dan tampilan yang disimpan
  • DI SINI ADALAH SATU YANG PALING PENTING UNTUK MASALAH ANDA :: Memungkinkan Anda untuk terhubung (sekali) bahkan jika batas koneksi yang dikendalikan oleh variabel sistem max_connections tercapai.

Anda harus masuk sebagai root @ localhost dan mencabut hak istimewa SUPER sebagai berikut:

UPDATE mysql.user SET super_priv='N'
WHERE super_priv='Y' AND
CONCAT(user,'@',host) <> 'root@localhost';
FLUSH PRIVILEGES;

Setelah Anda melakukan ini, setiap kali semua pengguna membanjiri koneksi mysql, hanya root@localhostdapat login. Lagipula, jika semua orang dan neneknya memiliki hak istimewa SUPER, ini akan menghalangi root@localhosthubungan yang ada di depan orang lain. Jika max_connections berada di 200 dan Anda perlu menaikkannya ke 300 tanpa harus me-restart mysqld, Anda dapat secara dinamis meningkatkan max_connections dengan perintah ini:

mysql> SET GLOBAL max_connections = 300;

Itu akan memungkinkan lebih banyak koneksi efektif dengan segera, tetapi jangan hanya secara sembarangan menambah nomor saat itu. Anda harus memastikan mysql memiliki cukup RAM untuk mengakomodasi peningkatan.

CAVEAT: Jika Anda mengubah max_connections secara dinamis menjadi 300, silakan letakkan di /etc/my.cnf

[mysqld]
max_connections=300

Anda dapat menjalankan mysqltuner.pl di MySQL DB Server Anda. Jika Anda tidak memilikinya, jalankan yang berikut ini:

cd
wget mysqltuner.pl
perl mysqltuner.pl

Baris ketiga di bawah Metrik Kinerja memiliki ini

-------- Performance Metrics -------------------------------------------------
[--] Up for: 8d 20h 46m 22s (8M q [10.711 qps], 129K conn, TX: 90B, RX: 19B)
[--] Reads / Writes: 4% / 96%
[--] Total buffers: 2.1G global + 5.4M per thread (2000 max threads)
[OK] Maximum possible memory usage: 12.6G (80% of installed RAM)

Lihat 5.4M per utas? Itu dikalikan dengan max_connections. Dalam contoh ini, itu akan menjadi maksimum sekitar 10,8G RAM. Oleh karena itu, setiap kali Anda menambah max_connections, Anda harus menjalankan mysqltuner.pl dan memeriksa apakah Anda menekan OS untuk terlalu banyak memori.

Dalam kasus apa pun, membatasi siapa yang memiliki hak SUPER memberikan kesempatan kepada pengguna tersebut untuk mengurangi banjir mysqld dengan Koneksi DB.

RolandoMySQLDBA
sumber
saya mendapatkan kesalahan ini ketika mencoba perl mysqltuner.pl "Mencoba menggunakan kredensial masuk dari akun pemeliharaan debian, tetapi gagal."
Shashank
Saya mencoba ini di server ubuntu lokal saya, ini menunjukkan penggunaan memori maksimum, tetapi pada vps saya, ini menunjukkan kegagalan dan saya tidak bisa login di phpmyadmin tetapi berhasil login di terminal mysql
Shashank
Cmd ini wget mysqltuner.pl, diunduh index.html, tetapi itu adalah file perl, jadi saya menamainya menjadi mysqltuner.pl dan cmd berikutnya perl mysqltuner.plberfungsi.
MotsManish
2
  1. Variabel global max_connectionsmenentukan jumlah maksimum koneksi konkuren ke MySQL. Pastikan Anda memiliki nilai tinggi untuk variabel ini. Anda dapat meningkatkan nilai ini menjadi 300 atau 400 dan mencoba me-restart MySQL setelah pengaturan ini.
  2. Rancang aplikasi Anda sedemikian rupa sehingga koneksi MySQL tetap terbuka untuk waktu yang sangat singkat.
  3. Anda juga harus memeriksa bahwa kode klien tidak menggunakan koneksi persisten (seperti mysql_pconnect ()) secara tidak benar.

Juga jalankan Flush status;perintah di server MySQl untuk mengurangi nilai ini.

Saya harap saran ini membantu.

Mahesh Patil
sumber
0

Periksa apakah disk Anda penuh, ini dapat menyebabkan kesalahan yang sama:

df -h

akan menunjukkan ruang yang tersisa pada setiap partisi, Anda mungkin harus memeriksa partisi root /(atau / var / jika Anda memiliki partisi tambahan untuk ini):

df -h /
rubo77
sumber