Situs WordPress Anda tiba-tiba menampilkan error koneksi database, dan saat diperiksa ternyata layanan MySQL sudah mati — tanpa ada yang menghentikannya. Di VPS Ubuntu dengan RAM kecil, pelaku yang paling sering adalah OOM killer: mekanisme kernel Linux yang, ketika memori benar-benar habis, memilih satu proses untuk dimatikan agar sistem tetap hidup. MySQL sering menjadi korbannya karena ia memakai memori paling besar.
Daftar Isi
- Jawaban Singkat
- Kenapa Kernel Membunuh Proses?
- Persiapan
- Langkah 1: Konfirmasi OOM Killer di Log
- Langkah 2: Hidupkan Kembali dan Bebaskan Memori
- Langkah 3: Turunkan Konsumsi Memori MySQL
- Langkah 4: Batasi PHP-FPM dan Tambahkan Swap
- Langkah 5: Lindungi MySQL dari Menjadi Korban Berikutnya
- Verifikasi Hasil
- Troubleshooting Lanjutan
- FAQ
- Kesimpulan
- Referensi
Jawaban Singkat
Konfirmasi dulu bahwa OOM killer memang pelakunya: periksa log kernel untuk baris Out of memory dan Killed process di sekitar waktu MySQL mati. Jika terbukti, solusinya ada dua lapis: jangka pendek, hidupkan kembali MySQL dan bebaskan memori (hentikan proses yang tidak perlu); jangka panjang, turunkan pemakaian memori MySQL dan PHP-FPM agar sesuai RAM VPS, tambahkan swap sebagai bantalan, dan lindungi MySQL dengan penyesuaian skor OOM. Menambah RAM tanpa menata konsumsi memori hanya menunda kejadian berikutnya.
Kenapa Kernel Membunuh Proses?
Kernel Linux mengizinkan proses meminta memori lebih besar dari RAM fisik (overcommit), dengan asumsi tidak semua permintaan dipakai sekaligus. Ketika semua proses benar-benar memakai jatahnya dan tidak ada lagi memori bebas, kernel harus memilih satu proses untuk dikorbankan — itulah OOM killer. Korbannya biasanya proses dengan memori terbesar dan skor keburukan tertinggi, yang bisa Anda lihat di /proc/[pid]/oom_score. Nilai penyesuai oom_score_adj berkisar -1000 (tidak akan dibunuh) sampai 1000 (paling mungkin dibunuh). Di Ubuntu modern ada juga systemd-oomd, layanan userspace yang memantau tekanan memori lewat cgroup dan bertindak sebelum OOM kernel terjadi.
Persiapan
- Buat backup database dan konfigurasi MySQL sebelum mengubah apa pun.
- Catat total RAM VPS (
free -h) dan pemakaian memori per layanan sebelum mengubah konfigurasi. - Jangan mengubah skor OOM menjadi -1000 untuk MySQL tanpa memahami risikonya: proses yang tidak bisa dibunuh membuat kernel memilih korban lain, atau sistem membeku.
Langkah 1: Konfirmasi OOM Killer di Log
sudo dmesg -T | grep -i -A2 "out of memory"
sudo journalctl -k --since "2 hours ago" | grep -i "killed process"
Cari baris yang menyebut proses mysqld/mariadbd beserta waktu kejadiannya. Jika tidak ada baris OOM, kematian MySQL punya penyebab lain (crash, konfigurasi, disk penuh) dan langkah-langkah di bawah tidak relevan — jangan memaksakan diagnosis OOM.
Langkah 2: Hidupkan Kembali dan Bebaskan Memori
sudo systemctl start mysql
free -h
ps aux --sort=-%mem | head -n 15
Perintah kedua dan ketiga menunjukkan siapa pemakai memori terbesar saat ini. Hentikan layanan yang tidak perlu (misalnya layanan pengembangan yang tertinggal di server produksi), dan periksa proses PHP-FPM serta cron berat yang berjalan bersamaan dengan kematian MySQL.
Langkah 3: Turunkan Konsumsi Memori MySQL
Di VPS kecil, konfigurasi bawaan MySQL sering terlalu boros. Sesuaikan di file konfigurasi MySQL (misalnya /etc/mysql/mysql.conf.d/mysqld.cnf), dengan nilai yang masuk akal untuk RAM Anda — contoh untuk VPS 2 GB:
innodb_buffer_pool_size = 512M
max_connections = 50
key_buffer_size = 32M
innodb_log_file_size = 128M
Buffer pool InnoDB adalah pemakai memori terbesar MySQL; menurunkannya adalah tuas paling efektif. Setelah mengubah konfigurasi, mulai ulang MySQL dan pantau pemakaiannya selama 24 jam sebelum menyatakan berhasil.
Langkah 4: Batasi PHP-FPM dan Tambahkan Swap
PHP-FPM yang worker-nya terlalu banyak adalah penyebab RAM penuh kedua yang paling umum di server WordPress. Hitung kebutuhan kasar: jumlah worker maksimum dikali memori per worker harus menyisakan ruang untuk MySQL, Nginx, dan sistem. Turunkan pm.max_children di pool www.conf bila perlu, dan pilih mode ondemand atau dynamic untuk situs dengan trafik tidak menentu. Kemudian tambahkan swap sebagai bantalan — swap tidak menggantikan RAM, tetapi memberi systemd-oomd dan kernel waktu bereaksi sebelum situasi menjadi kritis:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
Tambahkan entri /swapfile none swap sw 0 0 ke /etc/fstab agar swap aktif setelah reboot. Jangan membuka port atau layanan tambahan apa pun sebagai bagian dari perbaikan ini — itu tidak ada hubungannya dengan memori dan hanya menambah permukaan serangan.
Langkah 5: Lindungi MySQL dari Menjadi Korban Berikutnya
Daripada membuat MySQL tidak bisa dibunuh sama sekali, turunkan kemungkinan ia dipilih: pastikan bukan MySQL satu-satunya proses besar yang tidak terlindungi, dan atur layanan yang kurang penting agar lebih mungkin dikorbankan. Untuk layanan systemd, penyesuaian dapat dilakukan lewat OOMScoreAdjust di unit override — gunakan nilai negatif moderat (misalnya -100 hingga -200), bukan -1000. Cara yang lebih sehat tetap menata total konsumsi memori agar OOM tidak terjadi sama sekali.
Verifikasi Hasil
Perbaikan berhasil bila MySQL tetap hidup selama beban puncak, pemakaian memori total tidak lagi menyentuh 100% dalam pemantauan 24 jam, dan tidak ada lagi baris OOM baru di log kernel. Uji dengan beban yang menyerupai kejadian sebelumnya (misalnya menjalankan backup bersamaan dengan trafik normal) bila memungkinkan.
Troubleshooting Lanjutan
| Situasi | Langkah berikutnya |
|---|---|
| MySQL mati tetapi tidak ada baris OOM | Periksa log error MySQL dan ruang disk; penyebabnya bukan memori |
| OOM berulang pada jam yang sama | Periksa cron (backup, update, pemindaian) yang berjalan bersamaan |
| Swap penuh dan sistem lambat | Swap bukan solusi permanen; kurangi konsumsi memori atau naikkan RAM |
| PHP-FPM yang dibunuh, bukan MySQL | Turunkan max_children dan periksa skrip lambat yang menahan worker |
FAQ
Apakah menambah swap menyelesaikan OOM?
Tidak sepenuhnya. Swap memberi bantalan dan waktu reaksi, tetapi bila konsumsi memori terus melebihi kapasitas, OOM hanya tertunda dan sistem menjadi sangat lambat.
Kenapa yang mati MySQL, bukan proses lain?
Karena MySQL biasanya pemakai memori terbesar di server WordPress, sehingga skor OOM-nya tertinggi saat krisis terjadi.
Apakah aman mengatur oom_score_adj ke -1000 untuk MySQL?
Tidak disarankan. Kernel akan memilih korban lain atau sistem membeku. Gunakan nilai moderat dan utamakan menata konsumsi memori.
Kesimpulan
MySQL yang mati sendiri di VPS kecil hampir selalu jejak OOM killer. Konfirmasi dari log, hidupkan kembali, lalu tata ulang: buffer pool MySQL, worker PHP-FPM, dan swap sebagai bantalan. Lindungi MySQL secukupnya, tetapi ingat bahwa satu-satunya perbaikan permanen adalah konsumsi memori total yang muat di RAM Anda.
Referensi
- Ubuntu Manpage — systemd-oomd.service: manpages.ubuntu.com — systemd-oomd