Mengapa Apache berjalan liar dan membunuh MySQL?

8

Apache telah kehilangan kendali selama beberapa hari terakhir dan membuat MySQL crash dua kali. Semuanya berawal ketika saya memigrasikan situs WordPress yang juga berisi forum phpBB.

Saya tidak terlalu berpengalaman dalam admin server sehingga sangat sulit bagi saya untuk menentukan apa yang menyebabkan masalah. Ketika saya perhatikan bahwa MySQL sedang down, saya menjalankan TOP dan melihat lonjakan beban sistem saya ke 98.00. Server menjalankan 10 V-HOSTS yang semuanya menerima jumlah lalu lintas yang sehat jadi saya jelas melihat banyak proses apache-2 berjalan.

Beban server yang tinggi berlanjut selama 10 menit dan kemudian kembali ke keadaan normal. Saya tidak melihat lonjakan lalu lintas jaringan pada saat ini.

Sayangnya, logging kesalahan MySQL telah dinonaktifkan (sekarang diaktifkan kembali) sehingga tidak ada petunjuk di sana. Tapi saya cukup yakin itu karena Apache menghabiskan semua sumber daya, sehingga proses ID MySQL terbunuh.

Pertanyaan saya adalah:

Lain kali hal ini terjadi - bagaimana saya bisa mengidentifikasi apa yang menyebabkan lonjakan beban sistem? Mungkinkah skrip php yang menjadi gila? Mungkinkah itu serangan DDOS?

Apakah ada cara untuk memulai kembali MySQL secara otomatis saat macet?

Saya sekarang sudah menginstal htop. Mungkinkah ini lebih bermanfaat daripada top?

Di sini statistik server saya:

m1.xlarge (8 ECUs, 4 vCPUs, 15 GiB memory, 4 x 420 GiB Storage Capacity)
Ubuntu Server 12.04.3 LTS 
Bob Flemming
sumber
Meskipun log dinonaktifkan, apakah akan dmesgmembantu?
Daniel W.

Jawaban:

9

MySQL mungkin masih belum mencatat apa-apa, karena apa yang mungkin terjadi adalah bahwa ia sedang dibunuh oleh sistem karena tekanan memori sistem dari anak-anak apache. Seharusnya ada jejak dari ini di / var / log / syslog.

MySQL harus mencoba me-restart sendiri dalam crash atau pemutusan paksa, tetapi kecuali jika tersedia memori yang cukup, itu tidak bisa melakukan itu ... dan kegagalan kedua ini tidak dilihat oleh mysqld_safe sebagai "crash" tetapi lebih sebagai "penolakan untuk mulai, "jadi itu tidak akan terus mencoba. Upaya restart yang gagal sering disalahartikan oleh admin sebagai "crash," karena sifat kegagalan asli tersembunyi di balik pesan yang mudah diabaikan dalam log kesalahan MySQL:

mysqld_safe Number of processes running now: 0

Lihat InnoDB Crash Post Mortem untuk keadaan yang saya kira mirip dengan milik Anda.

Jawaban yang tampaknya sederhana untuk "mengapa" adalah bahwa antara Apache dan MySQL, beban yang Anda miliki, dan konfigurasi Anda saat ini, Anda tidak memiliki cukup memori pada mesin, dan ada beberapa titik kritis terkait dengan beban lalu lintas yang membawa kondisi ini keluar .

Apache melayani setiap permintaan browser bersamaan dari proses anak, sehingga dari jumlah koneksi bersamaan yang meningkat, jumlah anak akan meningkat. Pertama-tama Anda perlu membatasi nilai ini di konfigurasi apache sehingga Anda dapat memahami apa yang sebenarnya menyebabkan peningkatan koneksi bersamaan ... apakah ini hanya lonjakan lalu lintas yang berat namun sah? Semacam penolakan layanan? DB kueri yang menunda permintaan karena berjalan terlalu lama? Sesuatu perlu dioptimalkan?

http://httpd.apache.org/docs/2.2/mod/mpm_common.html#maxclients

Membatasi proses Apache secara bersamaan harus membantu mencegah hal ini, tetapi untuk menjadi jelas, itu naif untuk berpikir bahwa ini adalah solusi lengkap, jadi saya tidak ingin menyiratkan hal itu. Setelah proses dibatasi pada tingkat yang masuk akal atau setidaknya lebih aman, Anda dapat melanjutkan dengan mengidentifikasi apa yang sebenarnya terjadi. (Ada kontrol pengekangan lainnya di Apache, tapi itu bukan bidang keahlian saya.)

"Praktik terbaik" tentu saja menjalankan database Anda pada perangkat keras yang berbeda sehingga aplikasi tidak dapat membunuhnya. Meskipun tampaknya lebih efisien, di permukaan, untuk "memaksimalkan pemanfaatan" dari satu mesin dengan membagikannya, ini adalah ekonomi yang salah. Mayoritas memori yang digunakan oleh MySQL, dalam beban kerja yang khas, dialokasikan pada waktu startup, dan ditahan selama MySQL Server berjalan. Tuntutan pada CPU cenderung berbagi waktu puncak untuk MySQL dan Apache, karena mereka pada akhirnya melayani beban yang sama. Anda mungkin sebenarnya lebih baik dengan dua mesin m1.large daripada m1.xlarge tunggal, dan biayanya akan sama karena yang lebih kecil persis setengah dari harga yang lebih besar ... bahkan jika Anda sudah membayar di muka untuk diskon tambahan, perubahan ini dapat dilakukan .

Michael - sqlbot
sumber
Terima kasih atas balasan Anda, itu sangat membantu. Saya memeriksa / ver / log / syslog dan menemukan baris berikut: 18 Desember 15:48:38 ip-10-33-164-173 kernel: [29714591.071719] Kehabisan memori: Proses kill 28369 (mysqld) skor 21 atau pengorbanan child 18 Des 15:48:38 ip-10-33-164-173 kernel: [29714591.071753] Proses terbunuh 28369 (mysqld) total-vm: 2520332kB, anon-rss: 335304kB, file-rss: 0kB Jadi Anda pikir membatasi pengaturan maxclients di apache adalah cara terbaik untuk mencegah hal ini terjadi? Menurut Anda apa nilai yang lebih aman?
Bob Flemming
1
Saya akan menyarankan bahwa membatasi maksclients akan menjadi cara terbaik untuk memulai proses memahami keadaan yang berkontribusi terhadap longsoran salju apa pun yang Anda alami. Anda harus menghitung nilai yang lebih aman berdasarkan keadaan Anda, jumlah memori bebas pada sistem, dan jumlah memori khas yang Anda amati yang digunakan anak-anak apache. Terlalu rendah, dan permintaan akan mulai mencadangkan; terlalu tinggi dan Anda berada di tempat Anda sekarang. Kemudian memonitor proses yang muncul dan amati memori bebas dan log server Anda.
Michael - sqlbot
1

Anda memiliki beberapa poin untuk diperiksa:

-Periksa / var / log / messages: oomkiller dapat mematikan proses mysql jika tidak ada lagi memori yang digunakan. Periksa ram dengan bebas -lm (tanpa cache)

-Jika Anda menggunakan apache dengan prefork mpm: periksa jumlah proses. Jika apache menumpuk sejumlah proses penting (selama beban kerja yang berat) dengan tautan ke mysql, latensi dan memori yang digunakan dapat tumbuh dengan cepat.

-Periksa jumlah utas yang diluncurkan oleh mysql dengan status global show : threads_cached, threads_created dan threads_running penting untuk diperiksa (threads_created harus mendekati 0).

-Periksa ram yang digunakan oleh Mysql.

Jérémy Munoz
sumber
0

Anda juga bisa melihat menerapkan cpusets dan memesan sumber daya untuk mysql. Itu yang paling dekat dengan menjalankan layanan ini pada perangkat keras yang berbeda, namun tetap memberi Anda manfaat mempertahankan satu server.

skohrs
sumber