Skip to content
← Blog

Postmortem: Menangani “Too Many Connections” pada MySQL

Database sehat dengan connection pool dan failure isolation
Menambah max_connections dapat memberi waktu, tetapi akar masalah biasanya membutuhkan observability dan kontrol concurrency.

Skenario: pukul 01:00 UTC website mulai mengembalikan 503. Log menunjukkan SQLSTATE[08004] [1040] Too many connections. Menurut manual MySQL, error terjadi ketika seluruh koneksi yang diizinkan sedang digunakan; batas dikendalikan oleh max_connections.

Dampak#

  • Request yang membutuhkan database gagal selama 11 menit.
  • Halaman statis tetap tersedia.
  • Tidak ada kehilangan data yang teridentifikasi.
  • Analytics kehilangan sebagian event selama pemulihan.

Timeline contoh#

UTCPeristiwa
00:58Traffic crawler meningkat 4×
01:00Active connections menyentuh limit
01:02Alert 5xx aktif
01:05On-call memeriksa process list
01:08Endpoint mahal dibatasi
01:11Error rate normal

Diagnosis#

SHOW VARIABLES LIKE 'max_connections';
SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Threads_running';
SHOW FULL PROCESSLIST;

Threads_connected tinggi tetapi Threads_running rendah mengarah pada banyak koneksi idle. Banyak query state “Sending data” atau lock membutuhkan analisis berbeda. Periksa juga jumlah PHP worker: concurrency aplikasi × instance harus masuk budget database.

Five whys yang konkret#

  1. Mengapa request gagal? Semua slot koneksi terpakai.
  2. Mengapa slot penuh? Worker PHP menahan koneksi lebih lama saat query analytics lambat.
  3. Mengapa query lambat? Index pada kolom waktu tidak sesuai pola cleanup/report.
  4. Mengapa traffic memperparah? Endpoint dapat dipanggil crawler tanpa throttling.
  5. Mengapa terdeteksi terlambat? Alert hanya pada 5xx, bukan saturation connection.

Mitigasi segera#

  • Rate-limit endpoint sumber beban.
  • Hentikan job/report non-kritis.
  • Kill query tertentu hanya setelah memastikan dampak transaksi.
  • Naikkan limit sementara hanya bila memory dan kapasitas server mendukung.
  • Pertahankan akses admin darurat sesuai kemampuan server dan kebijakan privilege.

Perbaikan permanen#

  • Index query lambat dan batasi range laporan.
  • Set timeout aplikasi/database yang masuk akal.
  • Fail-open untuk analytics non-kritis.
  • Budget koneksi per service dan instance.
  • Alert pada 70/85/95% saturation.
  • Load test sampai bottleneck terlihat.
  • Runbook diagnosis yang tidak bergantung pada satu orang.

Apa yang tidak boleh ditulis#

“Developer lupa menutup koneksi” tanpa bukti. Pada PHP/PDO, lifetime request dan persistent connection memengaruhi perilaku; postmortem harus menunjukkan telemetry, konfigurasi, dan query. Fokus pada kondisi sistem yang memungkinkan kegagalan.

Action item baik: “Tambahkan dashboard Threads_connected/max_connections dan alert 85%, owner Platform, jatuh tempo 18 Agustus.” Action item buruk: “Lebih hati-hati.”

Connection budget#

DB limit aman: 200
Reserve admin/maintenance: 20
Budget aplikasi: 180
3 instances × 40 PHP workers = maksimum teoritis 120
Job/report budget = 30
Headroom = 30

Budget mencegah autoscaling aplikasi secara tidak sengaja melampaui kapasitas database. Jika persistent connection dipakai, pahami lifetime worker; jangan mengasumsikan koneksi ditutup setelah satu request.

Query dan index#

Connection saturation kadang gejala query lambat. Gunakan slow query log, execution plan, lock wait, dan histogram latency. Menambah koneksi ketika disk/CPU sudah jenuh dapat memperburuk antrean.

Game day#

  1. Turunkan limit di staging.
  2. Generate concurrency terkontrol.
  3. Pastikan alert saturation aktif sebelum 5xx.
  4. Ikuti runbook menggunakan akun admin yang tepat.
  5. Verifikasi optional feature fail-open.
  6. Ukur waktu recovery.

Definition of resolved#

Incident bukan selesai ketika service kembali hijau. Ia selesai ketika akar kondisi dipahami, action item memiliki owner/tanggal, alert diuji, dan perubahan kapasitas atau kode diverifikasi melalui load test.

💬 Comments (0)

No comments yet. Be the first to share your thoughts!

Related reading

Aug 11, 2026 · 2 min Mengapa Analytics Tidak Boleh Menjatuhkan Website Mendesain page-view tracking yang fail-open, non-blocking, terukur, dan tetap menjaga privasi ketika tabel analytics atau database bermasalah. Aug 11, 2026 · 3 min Stored XSS dan Rich Text Editor: Cara Membuat Sanitizer HTML yang Aman Membedakan escaping dan sanitization, menyusun allowlist tag/attribute/URL, serta menguji payload stored XSS pada rich text editor. Aug 11, 2026 · 2 min Membangun Website PHP Aman Tanpa Framework Studi kasus praktis membangun CSRF token, session hardening, prepared statement, upload validation, CSP, rate limiting, dan output encoding pada PHP native.
Now Playing Loading...