MySQL "Too Many Connections" Hatası - Production Site Çöküyor
Muzibu.com.tr sitesi bazen "Internal Server Error" veriyor ve sayfa açılmıyor. Kullanıcı sayfayı yenilediğinde tekrar çalışıyor. Bu durum site güvenilirliğini olumsuz etkiliyor.
Hata Mesajı: "SQLSTATE[HY000] [1040] Too many connections"
Anlamı: Veritabanı "Çok fazla bağlantı var, yeni bağlantı kabul edemiyorum" diyor.
Veritabanını bir restoran gibi düşünün:
Üç ana aksiyonla sorun çözülecek:
Bu düzeltmeler yapıldıktan sonra site kesintisiz çalışacak. Kullanıcılar "Too many connections" hatası almayacak.
max_connections: 151 Threads_connected: 53 Max_used_connections: 152 ⚠️ Connection_errors_max: 251 Max_used_time: 2026-01-09 11:15:28
Horizon Master: 2 (duplicate! ⚠️) Horizon Workers: 51 PHP-FPM Pools: ? Nginx Workers: ? Total Potential Conn: ~104
Dosya: routes/web.php:155-158
Route dosyası her HTTP request'te yüklendiği için, bu sorgu her sayfa yüklenişinde çalışıyor:
$muzibuDomains = \Illuminate\Support\Facades\DB::table('domains')
->where('tenant_id', 1001)
->pluck('domain')
->toArray();
Etki: Anasayfa 1000 kez ziyaret edildi → 1000 DB connection açıldı → Limit aşıldı!
İki adet Horizon master process çalışıyor (aynı supervisor config'i yüklüyor):
PID 1354897: /opt/plesk/php/8.5/bin/php artisan horizon PID 1359267: /opt/plesk/php/8.5/bin/php artisan horizon Her master 4 supervisor spawn ediyor: - ai-supervisor (max 2 worker) - tenant-supervisor (max 2 worker) - muzibu-supervisor (max 3 worker) - background-supervisor (max 1 worker) Toplam: 2 master × (2+2+3+1) = 16 supervisor Gerçek worker: 51 (her supervisor multiple worker spawn etmiş)
Etki: Gereksiz process → Gereksiz DB connection → CPU ve Memory yükü
Mevcut Limit: max_connections = 151
Gereksinim Hesabı:
Horizon Workers: 51 PHP-FPM pm.max_children: 50 (tahmini) Nginx Connections: 20 (tahmini) System/Admin: 10 Buffer: 20 ───────────────────────────── TOPLAM: ~151 (tam limit!) Yoğun saatlerde trafik artınca: 151+ → "Too many connections"
Etki: Yüksek trafikte sistem limit aşımı → Site çöküyor
Hata Zamanı: GET https://muzibu.com/ (Anasayfa)
Illuminate\Database\QueryException
SQLSTATE[HY000] [1040] Too many connections
Connection: mysql
SQL: select `domain` from `domains` where `tenant_id` = 1001
routes/web.php:157
→ \Illuminate\Support\Facades\DB::table('domains')
→ ->where('tenant_id', 1001)
→ ->pluck('domain')
⚠️ Hata routes yüklenirken oluşuyor, yani middleware'lerden önce!
Dosya: config/database.php:45-68
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'database' => env('DB_DATABASE', 'tuufi_4ekim'),
'username' => env('DB_USERNAME', 'tuufi_4ekim'),
'charset' => 'utf8mb4',
'options' => [
PDO::ATTR_TIMEOUT => 30,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
PDO::ATTR_PERSISTENT => false, ← Connection pooling KAPALI!
],
]
⚠️ ATTR_PERSISTENT => false her request yeni connection açıyor!
Sorun: Her HTTP request'te DB::table('domains') query'si çalışıyor.
Çözüm: Domain listesini Redis cache'e al, TTL: 3600 saniye (1 saat).
Strateji:
muzibu_domains_listBeklenen Sonuç:
1000 request → 1000 DB query (eski) | 1000 request → 1 DB query (yeni)
Kazanç: 999 DB connection azalma!
Sorun: İki adet Horizon master process çalışıyor (PID: 1354897, 1359267).
Çözüm: Tüm Horizon process'lerini temizle, Supervisor config kontrol et, tek master başlat.
Aksiyon:
php artisan horizon:terminate (graceful shutdown)pkill -9 -f "artisan horizon" (zorla temizle)/etc/supervisor/conf.d/php artisan horizonps aux | grep horizonBeklenen Sonuç:
51 worker → ~25 worker (yarı yarıya azalma)
Kazanç: ~26 DB connection azalma + CPU/Memory rahatlaması
Durum: Yukarıdaki düzeltmelerle sorun çözülecek, ancak güvenlik için limit artırılabilir.
Öneri: max_connections = 151 → 300 (2x artış)
Konfigürasyon (Plesk MySQL):
# /etc/my.cnf.d/server.cnf [mysqld] max_connections = 300 # Restart gerekli sudo systemctl restart mariadb
Beklenen Sonuç:
151 limit → 300 limit (yüksek trafik buffer)
Kazanç: Peak zamanlarda sistem çökmez
En büyük etki, hemen uygula! (999 DB query azalacak)
Orta etki, sistem performansı artacak (~26 process azalacak)
Güvenlik buffer, yukarıdaki düzeltmeler yeterli ama ekstra koruma
✅ Tahmini Toplam Süre: 15-20 dakika
✅ Downtime: YOK (Horizon restart hariç, ~30 saniye)
✅ Risk Seviyesi: Düşük (cache ve process yönetimi)
mysql -u tuufi_4ekim -p'XZ9Lhb%u8jp9#njf' -e "SHOW STATUS LIKE 'Threads_connected';" mysql -u tuufi_4ekim -p'XZ9Lhb%u8jp9#njf' -e "SHOW STATUS LIKE 'Max_used_connections';" # Beklenen: Threads_connected < 80 (151'in yarısından az)
ps aux | grep -E "(horizon|queue)" | grep -v grep | wc -l # Beklenen: ~25-30 (51'den azalmalı)
php artisan tinker
>>> Cache::get('muzibu_domains_list'); // Domain listesi dönmeli
>>> Cache::has('muzibu_domains_list'); // true olmalı
tail -f storage/logs/laravel.log