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.
Angka 80% ditulis untuk server yang isinya cuma database
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.
Buffer pool bukan satu-satunya memori yang dipakai MySQL
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.
Aman setelah restart belum tentu aman seminggu kemudian
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.
Buffer pool lebih besar tidak otomatis bikin situs lebih cepat
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.
Cara menghitung dari sisa RAM, bukan dari total RAM
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_%';"- 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.
- Hitung web server. Nginx atau LiteSpeed biasanya kecil, tapi tetap ukur dari RSS prosesnya.
- Hitung PHP-FPM:
pm.max_childrendikali 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. - Hitung cache. Untuk Redis, pakai nilai
maxmemoryditambah sedikit overhead. Kalaumaxmemorybelum diset, artinya Redis belum punya batas, dan itu masalah tersendiri. - Sisihkan memori per koneksi MySQL untuk jumlah koneksi aktif yang realistis, bukan nilai
max_connections. - Sisanya adalah batas atas buffer pool. Bandingkan dengan total data dan index InnoDB, lalu ambil yang lebih kecil dan beri ruang untuk pertumbuhan data.
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.