Bali, Indonesia
Insights

Mengira innodb_buffer_pool_size 80% RAM Aman untuk VPS yang Juga Jalankan Web

October 22, 2026
0:00
Kalau kamu cari panduan tuning MySQL, angka 80% RAM untuk innodb_buffer_pool_size hampir selalu muncul. Angkanya gampang diingat, jadi banyak admin langsung menyalinnya ke VPS 2 atau 4 GB yang juga menjalankan Nginx atau LiteSpeed, PHP-FPM, dan Redis. Gejalanya biasanya mirip: server mulai swap, situs makin lambat, lalu MySQL mati tiba-tiba dan di log kernel ada jejak OOM killer, yaitu mekanisme Linux yang mematikan proses saat memori benar-benar habis. Yang salah bukan MySQL-nya, tapi anggapan bahwa aturan itu berlaku untuk semua server. Ada beberapa salah kaprah yang sering muncul bareng. Kita bahas satu per satu, lalu lanjut ke cara menghitung angka yang lebih masuk akal.
Aturan ini terasa benar karena sumbernya kredibel. Dokumentasi MySQL memang menyebut angka sekitar 80% sebagai titik awal. Tapi konteksnya server database dedicated, yaitu mesin yang tugasnya hanya menjalankan MySQL. Buffer pool adalah area memori tempat InnoDB menyimpan halaman data dan index yang sering dibaca. Tujuannya supaya query tidak perlu bolak-balik ke disk. Di server database khusus, sisa 20% RAM cukup untuk OS, koneksi MySQL, dan sedikit page cache. Tidak ada proses lain yang berebut. Di VPS web, 20% itu harus dibagi ke web server, semua worker PHP-FPM, Redis atau Memcached, cron, proses backup, dan kadang mail server. Di VPS 4 GB, 20% artinya sekitar 800 MB untuk semua itu. Situs WordPress dengan beberapa worker PHP saja sudah bisa melewati angka itu saat jam ramai. MySQL 8.0 juga punya opsi innodb_dedicated_server yang mengatur ukuran buffer pool otomatis berdasarkan RAM. Namanya sudah menjelaskan untuk siapa opsi itu dibuat. Mengaktifkannya di VPS yang juga melayani web kurang lebih sama dengan menyalin aturan 80% tadi, hanya saja dilakukan otomatis.
Salah kaprah kedua: kalau buffer pool diset 3 GB, berarti MySQL memakai 3 GB. Kenyataannya, proses mysqld hampir selalu memakai lebih dari itu. Pertama, InnoDB butuh sedikit memori tambahan untuk struktur kontrol buffer pool, jadi alokasinya sedikit lebih besar dari angka yang kamu tulis. Kedua, ada memori yang dipakai per koneksi: sort_buffer_size untuk sorting, join_buffer_size untuk join tanpa index yang cocok, read_buffer_size dan read_rnd_buffer_size untuk pembacaan tertentu, serta tabel sementara di memori yang dibatasi tmp_table_size dan max_heap_table_size. Buffer ini dialokasikan saat dibutuhkan, dan satu query yang rumit bisa memakai lebih dari satu buffer sekaligus. Ketiga, ada log buffer, stack untuk tiap thread, dan performance_schema. Saat koneksi aktif sedikit, tambahan ini kecil. Saat traffic naik dan banyak worker PHP membuka koneksi bersamaan, totalnya bisa ratusan MB. Jadi menghitung memori MySQL dari buffer pool saja hampir pasti meleset ke bawah.
Ini salah kaprah yang paling menipu. Setelah buffer pool diubah ke 80% dan MySQL di-restart, server terlihat normal. RAM masih longgar dan situs cepat, jadi kesimpulannya setting aman. Masalahnya, Linux tidak langsung memberikan memori fisik untuk seluruh buffer pool saat MySQL start. Halaman baru benar-benar dipakai saat InnoDB mengisinya dengan data. Akibatnya, pemakaian memori fisik mysqld (RSS, resident set size) naik pelan seiring waktu. Operasi yang membaca banyak tabel, seperti mysqldump, ALTER TABLE di tabel besar, atau query tanpa index, mempercepat proses ini karena halaman yang dibaca ikut masuk ke buffer pool. Di saat yang sama, layanan lain juga bertambah. PHP-FPM dengan mode dynamic menambah worker saat ramai, worker yang sudah lama hidup biasanya makin besar, dan cron atau backup muncul di jam tertentu. Begitu total kebutuhan melewati RAM ditambah swap, OOM killer memilih proses dengan skor tertinggi. Biasanya itu proses dengan memori terbesar, dan di server seperti ini prosesnya hampir selalu mysqld. Swap juga tidak benar-benar menolong. Kalau sebagian halaman buffer pool dipindah ke swap, InnoDB tetap menganggap data itu ada di memori, padahal sebenarnya harus dibaca lagi dari disk lewat swap. Tujuan buffer pool hilang, dan hasilnya sering lebih lambat dibanding buffer pool kecil yang tetap utuh di RAM. Dari sisi support, pola ini sering muncul sebagai keluhan error koneksi database yang datang dan hilang tanpa sebab jelas. Hal pertama yang layak dicek adalah log kernel, bukan konfigurasi WordPress.
Logikanya terdengar wajar: makin banyak data di memori, makin jarang baca disk, makin cepat. Itu benar sampai titik tertentu, yaitu saat working set, bagian data yang sering diakses, sudah muat di buffer pool. Setelah itu, menambah ukuran hampir tidak menambah kecepatan. Banyak situs di VPS kecil punya total data dan index InnoDB yang jauh lebih kecil dari RAM. Bagian yang sering diakses biasanya lebih kecil lagi. Buffer pool 3 GB untuk data 600 MB tidak membuat query lebih cepat. Efeknya hanya batas atas yang terlalu longgar: saat data tumbuh atau ada proses yang membaca banyak tabel, MySQL boleh memakai memori sebanyak itu, padahal memorinya sebenarnya dibutuhkan PHP-FPM. Untuk menilai apakah buffer pool kekecilan, lihat statistiknya. Innodb_buffer_pool_read_requests menghitung permintaan baca ke buffer pool. Innodb_buffer_pool_reads menghitung permintaan yang terpaksa ke disk karena halamannya belum ada di memori. Kalau angka kedua sangat kecil dibanding yang pertama setelah server berjalan cukup lama, buffer pool sudah cukup. Innodb_buffer_pool_pages_free yang masih banyak juga tanda ukurannya lebih dari yang dibutuhkan.
Sebelum mengubah angka, kumpulkan data dulu. Perintah berikut hanya membaca dan aman dijalankan:
BASH
# Cek apakah kernel pernah mematikan proses karena kehabisan memori (butuh root)
dmesg -T | grep -i -E 'out of memory|killed process'

# Total ukuran data + index tabel InnoDB, dalam MB
mysql -e "SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024) AS total_mb FROM information_schema.tables WHERE engine = 'InnoDB';"

# Statistik buffer pool: halaman kosong, permintaan baca, dan baca yang terpaksa ke disk
mysql -e "SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_%';"
Kalau dmesg kosong padahal kamu curiga ada OOM, cek juga journal kernel. Buffer dmesg bisa sudah ter-rotate. Setelah itu, hitung dengan urutan berikut:
  1. Sisihkan memori untuk OS, kernel, dan sedikit page cache. Jangan dihitung nol, karena filesystem tetap butuh cache supaya file PHP dan aset statis tidak selalu dibaca dari disk.
  2. Hitung web server. Nginx atau LiteSpeed biasanya kecil, tapi tetap ukur dari RSS prosesnya.
  3. Hitung PHP-FPM: pm.max_children dikali rata-rata RSS satu worker saat jam ramai, bukan saat server sepi. Kalau worker sering habis di jam ramai, baca juga pembahasan PHP-FPM pool starvation sebelum menaikkan jumlahnya.
  4. Hitung cache. Untuk Redis, pakai nilai maxmemory ditambah sedikit overhead. Kalau maxmemory belum diset, artinya Redis belum punya batas, dan itu masalah tersendiri.
  5. Sisihkan memori per koneksi MySQL untuk jumlah koneksi aktif yang realistis, bukan nilai max_connections.
  6. Sisanya adalah batas atas buffer pool. Bandingkan dengan total data dan index InnoDB, lalu ambil yang lebih kecil dan beri ruang untuk pertumbuhan data.
Contoh ilustratif untuk VPS 4 GB, dengan angka yang sengaja dibulatkan: sekitar 500 MB untuk OS dan page cache minimum, 100 MB untuk web server, 10 worker PHP-FPM × 60 MB = 600 MB, Redis dibatasi 256 MB, sekitar 400 MB untuk koneksi MySQL, dan 500 MB cadangan untuk cron dan backup. Sisanya sekitar 1,7 GB, jadi buffer pool 1,5 GB lebih masuk akal. Itu kurang dari 40% RAM, jauh dari 80%. Kalau total data InnoDB-nya hanya 700 MB, buffer pool 1 GB pun sudah cukup. Di versi MySQL dan MariaDB yang masih didukung, innodb_buffer_pool_size biasanya bisa diubah saat server berjalan. Tetap tulis nilainya di file konfigurasi supaya tidak kembali ke nilai lama setelah restart. Lokasi file konfigurasi berbeda tergantung distro dan control panel, jadi cek dulu file mana yang benar-benar dibaca MySQL di server kamu. Setelah diubah, pantau RSS mysqld, pemakaian swap, dan log kernel selama beberapa hari, termasuk saat jam ramai dan saat backup berjalan. Aturan 80% bukan aturan yang salah. Aturan itu dibuat untuk server yang hanya menjalankan database. Di VPS yang melayani web, buffer pool adalah apa yang tersisa setelah layanan lain kebagian memori, dan angkanya cukup sebesar data yang sering diakses. Kalau MySQL pernah dimatikan OOM killer, hampir selalu lebih aman mengecilkan buffer pool sedikit daripada berharap swap akan menutup kekurangannya.