📑 Daftar Isi
- Gejala & Error Message yang Muncul
- Kenapa MySQL / MariaDB Mati Sendiri di VPS RAM Kecil?
- OOM Killer:「Hakim」di Balik Layar
- Cara Kerja OOM Killer
- Cara Cek Log OOM Killer
- Mengapa VPS 1GB–2GB Rentan?
- Solusi Konkret: 3 Langkah Wajib
- Solusi 1: Pasang SWAP File
- Solusi 2: Tuning innodb_buffer_pool_size
- Solusi 3: Batasi max_connections
- Langkah Tambahan yang Sering Dilupakan
- Troubleshooting Table: MySQL Mati Sendiri
- Pro Tips & Warning
- Kapan Harus Upgrade VPS?
Jadi ceritanya begini — beberapa waktu lalu saya handle client yang pakai VPS 1GB RAM buat jalanin website WordPress biasa. Tidak ada traffic gila-gilaan, tidak ada plugin berat. Tapi tiap 2-3 hari sekali, website-nya down. Error 502 Bad Gateway. Kadang muncul Error establishing a database connection. Saya coba restart MySQL, jalan lagi sebentar, terus mati lagi. Client-nya udah stres banget, katanya “Kok kayaknya VPS-nya jelek ya?”
Nah, ini yang sering saya temuin di VPS RAM kecil (1GB–2GB). MySQL atau MariaDB mati sendiri tanpa pesan error yang jelas. Kamu cek log error-nya, tidak ada yang fatal. Restart service, jalan lagi. Tapi beberapa jam kemudian, down lagi. Bikin pengen lempar laptop ke tembok.
Ternyata, pelakunya bukan MySQL-nya yang rusak. Pelakunya adalah OOM Killer — fitur di Linux yang「membunuh」proses yang dianggap makan RAM terlalu banyak. Dan MySQL, sayangnya, sering jadi korban pertama.
Di artikel ini, kita akan bahas tuntas kenapa ini terjadi, gimana cara cek-nya, dan solusi konkret yang bisa kamu langsung terapkan hari ini juga.
Gejala & Error Message yang Muncul
Sebelum masuk ke solusi, penting banget buat kamu bisa mengenali gejalanya. Ini bukan error biasa yang langsung kasih pesan jelas. Seringkali gejalanya「halus」dan bikin bingung.
Ini beberapa gejala yang paling sering muncul:
- 502 Bad Gateway — web server (Nginx/Apache) tidak bisa koneksi ke PHP-FPM atau backend
- Error establishing a database connection — WordPress/CMS tidak bisa koneksi ke MySQL
- MySQL service status: inactive (dead) — tapi tidak ada error di log MySQL sendiri
- Website loading sangat lambat sebelum akhirnya benar-benar down
- Server jadi sangat lambat secara keseluruhan — bahkan SSH session terasa lag
Yang bikin bingung adalah: kalau kamu restart MySQL (systemctl restart mysqld atau systemctl restart mariadb), semuanya normal lagi. Website jalan. Tapi beberapa jam atau hari kemudian, masalah yang sama muncul lagi.
Kenapa MySQL / MariaDB Mati Sendiri di VPS RAM Kecil?
OOM Killer:「Hakim」di Balik Layar
Bayangkan VPS kamu itu kayak sebuah ruangan kecil (1GB–2GB RAM). Di ruangan itu ada beberapa「penghuni」: sistem operasi, web server (Nginx/Apache), PHP-FPM, MySQL/MariaDB, dan mungkin service lain seperti Redis atau Cron.
Setiap「penghuni」butuh「tempat duduk」(RAM) buat kerja. Kalau semuanya masih muat, tidak ada masalah. Tapi begitu ruangan mulai penuh, ada「pengawas」namanya OOM Killer yang akan「mengusir」penghuni yang paling banyak makan tempat.
MySQL/MariaDB itu「penghuni」yang paling sering kena usir, karena memang dia punya kebiasaan menggunakan RAM yang lumayan banyak — terutama untuk InnoDB buffer pool, query cache, dan koneksi aktif.
Ketika OOM Killer menjalankan「hukuman」ini, proses MySQL langsung di-kill secara paksa oleh kernel Linux. Tidak ada graceful shutdown, tidak ada error message di MySQL log. Service-nya tiba-tiba mati. Dan karena tidak ada graceful shutdown, kadang ada sedikit corruption di data (jarang, tapi bisa terjadi).
Cara Kerja OOM Killer
Secara teknis, begini prosesnya:
- Linux kernel memantau penggunaan RAM terus-menerus
- Ketika RAM hampir habis dan sistem tidak bisa mengalokasikan memory baru untuk proses yang membutuhkan
- OOM Killer diaktifkan dan mulai menghitung「skor」tiap proses
- Proses dengan skor tertinggi (biasanya yang paling banyak pakai RAM) akan di-kill
- MySQL/MariaDB sering jadi skor tertinggi karena buffer pool dan active connections
Yang bikin frustasi: OOM Killer tidak meninggalkan「bekas」yang terlihat jelas di log MySQL. Kamu tidak akan lihat error di /var/log/mysql/error.log atau /var/log/mariadb/mariadb.log. Pesan「kematian」MySQL dicatat di tempat lain — yaitu di dmesg atau /var/log/messages.
Cara Cek Log OOM Killer
Ini langkah pertama yang harus kamu lakukan kalau curiga MySQL mati karena OOM. Jalankan perintah berikut:
dmesg | grep -i oom
Atau kalau kamu pakai systemd, bisa juga cek:
dmesg | grep -i "out of memory"
Contoh output yang menunjukkan OOM Killer aktif:
[Jul 20 03:42:15] Out of memory: Kill process 1245 (mysqld) score 850 or sacrifice child
[Jul 20 03:42:15] Killed process 1245 (mysqld) total-vm:892412kB, anon-rss:651204kB, file-rss:0kB, shmem-rss:0kB
Lihat output di atas — ini「bukti pembunuhan」nya. Linux bilang: proses mysqld (PID 1245) di-kill karena terlalu banyak makan RAM (651MB anon-rss). Opsi lainnya adalah cek di /var/log/messages atau /var/log/syslog:
grep -i "out of memory" /var/log/messages
Atau untuk Debian/Ubuntu:
grep -i "out of memory" /var/log/syslog
Kamu juga bisa cek apakah MySQL benar-benar mati (bukan cuma restart sendiri) dengan:
systemctl status mysqld
atau untuk MariaDB:
systemctl status mariadb
Kalau statusnya inactive (dead) tapi tidak ada restart timestamp baru-baru ini, kemungkinan besar memang OOM Killer yang「membunuh」.
Mengapa VPS 1GB–2GB Rentan?
Pertanyaannya: kenapa ini lebih sering terjadi di VPS RAM kecil?
Jawabannya sederhana — headroom. Di VPS RAM besar (4GB, 8GB, dst), ada「sisa」RAM yang cukup buat menampung lonjakan usage. Tapi di VPS 1GB–2GB, batasnya sangat tipis.
Berikut perkiraan RAM usage di VPS 1GB yang menjalankan stack umum:
| Service | Estimasi RAM | Keterangan |
|---|---|---|
| OS + Systemd | ~100–150 MB | Minimal untuk boot |
| Nginx / Apache | ~30–80 MB | Tergantung config & traffic |
| PHP-FPM | ~50–150 MB | Tergantung max_children |
| MySQL / MariaDB | ~200–400 MB | Tergantung innodb_buffer_pool_size |
| SSH + System process | ~50–80 MB | Digunakan terus-menerus |
| Total | ~430–860 MB | Hampir mendekati batas 1GB |
Sekarang bayangkan saat traffic naik — PHP-FPM spawn lebih banyak worker, MySQL dapat lebih banyak query, Nginx handle lebih banyak request. RAM yang「sisa」langsung habis, dan OOM Killer mulai bekerja.
Solusi Konkret: 3 Langkah Wajib
Solusi 1: Pasang SWAP File
SWAP itu ibarat「ruang cadangan」di hard disk yang bisa dipakai sebagai「RAM tambahan」saat RAM asli sudah penuh. Iya, lebih lambat dari RAM asli, tapi jauh lebih baik daripada MySQL di-kill OOM.
Buat kamu yang VPS-nya belum punya SWAP, ini langkah wajib. Saya biasanya pasang minimal 1GB–2GB SWAP untuk VPS RAM 1GB.
Cara cek apakah sudah ada SWAP:
free -h
Contoh output jika belum ada SWAP:
total used free shared buff/cache available
Mem: 988Mi 412Mi 85Mi 12Mi 490Mi 530Mi
Swap: 0B 0B 0B
Lihat baris Swap — kalau total-nya 0B, berarti belum ada SWAP. Kalau sudah ada, kamu bisa skip langkah ini atau tambah kalau kurang.
Langkah-langkah pasang SWAP 1GB:
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
Verifikasi SWAP sudah aktif:
free -h
Sekarang kamu harus lihat baris Swap menunjukkan total 1GB:
total used free shared buff/cache available
Mem: 988Mi 412Mi 85Mi 12Mi 490Mi 530Mi
Swap: 1.0Gi 15Mi 1.0Gi
Agar SWAP tetap aktif setelah reboot:
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Optimasi SWAP usage (opsional tapi recommended):
Kamu bisa atur「kapan」Linux mulai pakai SWAP dengan vm.swappiness. Default-nya biasanya 60, artinya Linux mulai pakai SWAP saat RAM terpakai 40%. Untuk VPS, saya biasanya set ke 10 supaya SWAP hanya dipakai saat benar-benar mendesak:
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Peringatan: SWAP bukan solusi permanen untuk masalah RAM yang terlalu kecil. SWAP hanya「peredam」agar MySQL tidak langsung di-kill OOM. Kalau website-nya memang butuh RAM lebih, pertimbangkan upgrade VPS.
Solusi 2: Tuning innodb_buffer_pool_size
innodb_buffer_pool_size adalah「rumah utama」MySQL untuk menyimpan data/index di RAM. Default-nya bisa sangat besar — di beberapa distribusi, bisa 256MB atau bahkan 128MB. Di VPS RAM 1GB, ini terlalu besar.
Aturan praktis yang saya pakai: innodb_buffer_pool_size tidak boleh lebih dari 50% total RAM. Untuk VPS 1GB, set ke 128MB–256MB sudah cukup. Untuk VPS 2GB, bisa naik ke 384MB–512MB.
Langkah tuning:
Buka file konfigurasi MySQL/MariaDB:
Untuk MySQL:
sudo nano /etc/mysql/my.cnf
Untuk MariaDB:
sudo nano /etc/my.cnf
Atau kalau pakai AlmaLinux/RHEL-based:
sudo nano /etc/my.cnf.d/mariadb-server.cnf
Cari bagian [mysqld] dan tambahkan/ubah parameter berikut:
[mysqld]
innodb_buffer_pool_size = 128M
innodb_log_file_size = 32M
innodb_log_buffer_size = 8M
key_buffer_size = 32M
max_allowed_packet = 64M
Penjelasan singkat tiap parameter:
| Parameter | Fungsi | Rekomendasi VPS 1GB | Rekomendasi VPS 2GB |
|---|---|---|---|
innodb_buffer_pool_size |
RAM untuk cache data & index InnoDB | 128M | 256M–384M |
innodb_log_file_size |
Ukuran redo log (performa write) | 32M | 64M |
innodb_log_buffer_size |
Buffer untuk redo log sebelum flush | 8M | 16M |
key_buffer_size |
RAM untuk MyISAM index cache | 32M | 64M |
max_allowed_packet |
Ukuran maksimal paket data | 64M | 64M |
Setelah edit, restart MySQL/MariaDB:
sudo systemctl restart mysqld
Atau untuk MariaDB:
sudo systemctl restart mariadb
Verifikasi setting baru sudah diterapkan:
mysql -u root -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
Output yang diharapkan:
+---------------------+-----------+
| Variable_name | Value |
+---------------------+-----------+
| innodb_buffer_pool_size | 134217728 |
+---------------------+-----------+
134217728 bytes = 128MB. Kalau angka ini sesuai yang kamu set, berarti berhasil.
Solusi 3: Batasi max_connections
Setiap koneksi ke MySQL mengonsumsi RAM — biasanya 2–5MB per koneksi, tergantung query yang dijalankan. Kalau max_connections terlalu tinggi, MySQL bisa「memakan」semua RAM hanya untuk menampung koneksi-koneksi ini.
Di VPS 1GB, saya rekomendasikan max_connections sekitar 30–50. Untuk VPS 2GB, bisa naik ke 50–100.
Edit file konfigurasi yang sama (/etc/mysql/my.cnf atau /etc/my.cnf):
[mysqld]
max_connections = 30
wait_timeout = 60
interactive_timeout = 60
Parameter wait_timeout dan interactive_timeout memastikan koneksi idle yang tidak aktif akan ditutup setelah 60 detik, sehingga tidak「membuang」RAM untuk koneksi yang tidak dipakai.
Restart MySQL/MariaDB:
sudo systemctl restart mysqld
Verifikasi:
mysql -u root -p -e "SHOW VARIABLES LIKE 'max_connections';"
Kamu juga bisa memantau jumlah koneksi aktif kapan saja:
mysql -u root -p -e "SHOW STATUS LIKE 'Threads_connected';"
Atau untuk monitoring real-time, gunakan:
watch -n 2 "mysqladmin -u root -p status | awk '{print "Threads: "$9}'"
Langkah Tambahan yang Sering Dilupakan
Cek Service Lain yang Makan RAM Berlebihan
Seringkali bukan hanya MySQL yang「bersalah」. Service lain juga bisa jadi biang keladi. Cek RAM usage secara real-time:
sudo ps aux --sort=-%mem | head -20
Contoh output:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
mysql 1245 2.1 28.5 892412 281200 ? Sl 03:20 1:42 /usr/sbin/mysqld
root 892 0.8 12.3 231456 121504 ? Ss 03:20 0:45 /usr/sbin/httpd
root 1034 1.2 8.1 156789 80123 ? S 03:20 0:33 php-fpm: pool www
redis 567 0.3 4.2 75632 41234 ? Ssl 03:20 0:12 redis-server 127.0.0.1:6379
Dari output di atas, kamu bisa lihat siapa yang paling banyak makan RAM. MySQL memang paling besar (28.5%), tapi httpd (12.3%) dan php-fpm (8.1%) juga「menyumbang」.
Kalau kamu pakai Redis, pastikan juga Redis tidak pakai terlalu banyak RAM:
sudo nano /etc/redis/redis.conf
Cari maxmemory dan set ke nilai yang wajar (misal 64MB untuk VPS 1GB):
maxmemory 64mb
maxmemory-policy allkeys-lru
Monitoring Proaktif dengan Cron
Supaya tidak「kejadian terus-menerus」, kamu bisa buat script sederhana yang otomatis restart MySQL kalau dia mati:
sudo nano /usr/local/bin/mysql-watchdog.sh
Isi script-nya:
#!/bin/bash
if ! systemctl is-active --quiet mysqld; then
echo "$(date): MySQL is down, restarting..." >> /var/log/mysql-watchdog.log
systemctl restart mysqld
fi
Buat executable:
sudo chmod +x /usr/local/bin/mysql-watchdog.sh
Tambahkan cron job (setiap 5 menit):
sudo crontab -e
Tambahkan baris ini:
*/5 * * * * /usr/local/bin/mysql-watchdog.sh
Tapi ingat — ini hanya「patch」bukan solusi permanen. Kalau MySQL mati karena OOM, kamu harus mengatasi root cause-nya (RAM tidak cukup, konfigurasi tidak optimal).
Troubleshooting Table: MySQL Mati Sendiri
| Gejala | Kemungkinan Penyebab | Cara Cek | Solusi |
|---|---|---|---|
| MySQL mati tanpa error log | OOM Killer | dmesg | grep -i oom |
Pasang SWAP + tuning buffer pool |
| 502 Bad Gateway sesekali | PHP-FPM kehabisan RAM | sudo ps aux --sort=-%mem |
Set pm.max_children lebih rendah |
| MySQL mati pas traffic tinggi | max_connections terlalu tinggi | SHOW STATUS LIKE 'Threads_connected' |
Batasi max_connections |
| Server lag + MySQL mati | Tidak ada SWAP + RAM kecil | free -h |
Pasang SWAP 1–2GB |
| MySQL restart otomatis tapi sering | Watchdog/restart policy aktif | systemctl status mysqld |
Perbaiki root cause, jangan andalkan restart |
| Error InnoDB crash recovery | Hard shutdown (OOM kill) | cat /var/log/mysql/error.log | tail -50 |
Tuning buffer pool + pasang SWAP |
Pro Tips & Warning
Pro Tip: Kalau kamu pakai cPanel, pastikan juga untuk cek /etc/my.cnf — cPanel kadang punya konfigurasi default yang agak「boros」RAM untuk shared hosting environment. Cek juga WHM → Service Configuration → MySQL Configuration untuk tuning dari panel.
Warning: Jangan pernah set innodb_buffer_pool_size lebih dari 60% total RAM di VPS kecil. Ini kesalahan paling sering yang saya lihat. MySQL mungkin「hidup」tapi performanya malah lebih buruk karena sering swap-in/swap-out.
Pro Tip: Kalau kamu pakai AlmaLinux/RHEL, cek juga apakah firewalld atau SELinux sedang「makan」RAM ekstra. Nonaktifkan SELinux jika tidak diperlukan: sudo setenforce 0 dan edit /etc/selinux/config untuk permanent.
Warning: SWAP di SSD VPS bisa mempercepat「kematian」SSP karena terlalu banyak write cycle. Kalau VPS kamu pakai SSD, pertimbangkan untuk pasang SWAP dengan ukuran tidak terlalu besar (512MB–1GB) dan gunakan swappiness rendah (10).
Kapan Harus Upgrade VPS?
Jujur saja — semua solusi di atas adalah「obat pereda nyeri」. Kalau website kamu memang sudah mulai「berat」(banyak plugin, traffic naik, multiple sites di satu VPS), saatnya upgrade RAM.
Tanda-tanda kamu butuh upgrade:
- SWAP usage konsisten di atas 50%
- MySQL restart sendiri lebih dari 2x seminggu meski sudah dituning
- Website loading time terus naik tanpa perubahan config
- Kamu menjalankan lebih dari 1 website di VPS 1GB
Pertimbangkan upgrade ke VPS 4GB atau gunakan managed database service (seperti AWS RDS, DigitalOcean Managed Database) kalau budget memungkinkan.
Q: Apakah OOM Killer hanya membunuh MySQL, atau bisa service lain juga?
OOM Killer bisa membunuh service apapun, bukan cuma MySQL. Tapi MySQL memang「korban favorit」karena biasanya menggunakan RAM paling banyak di antara semua service di VPS. Service lain seperti PHP-FPM, Redis, atau bahkan web server (Nginx/Apache) juga bisa di-kill oleh OOM Killer. Kamu bisa cek semua korban dengan dmesg | grep -i kill.
Q: Apakah menambah SWAP bisa menggantikan upgrade RAM?
Tidak. SWAP hanya「peredam」agar proses tidak langsung di-kill OOM. Karena SWAP menggunakan hard disk (bahkan SSD), akses-nya jauh lebih lambat dari RAM asli. Website kamu akan「hidup」tapi performanya akan menurun signifikan saat banyak menggunakan SWAP. SWAP adalah solusi sementara atau「safety net」, bukan pengganti RAM yang sebenarnya.
Q: Kenapa saya sudah tuning tapi MySQL masih mati juga?
Kemungkinan ada service lain yang「mencuri」RAM. Cek dengan sudo ps aux --sort=-%mem | head -20 untuk melihat siapa yang paling banyak makan RAM saat itu. Bisa juga karena PHP-FPM pm.max_children terlalu tinggi, atau ada script cron yang makan RAM banyak. Jika semua sudah dituning dan masih mati, memang saatnya upgrade RAM atau gunakan managed database.