MySQL Too Many Connections Hatası Çözümü
MySQL Too Many Connections hatası, eş zamanlı bağlantı sayısı limitini aştığında oluşur. max_connections ve bağlantı havuzu ile çözülür.
MySQL "Too Many Connections" Hatası Nedir?
MySQL veritabanı sunucunuza bağlanmaya çalışırken "Too Many Connections" hatasıyla karşılaşıyorsanız, bu sunucunun izin verdiği maksimum eş zamanlı bağlantı sayısına ulaşıldığı anlamına gelir. MySQL, varsayılan olarak en fazla 151 eş zamanlı bağlantıya izin verir. Bu sayının bir fazlası (151. bağlantı) yönetici bağlantısı için ayrılmıştır, dolayısıyla normal kullanıcılar için gerçek limit 150'dir.
Hata mesajı şu şekilde görünür:
ERROR 1040 (HY000): Too many connections
Bu hata özellikle yüksek trafikli web sitelerinde, optimize edilmemiş uygulamalarda ve bağlantı havuzu kullanılmayan projelerde sık görülür.
Hatanın Nedenleri
1. Düşük max_connections Değeri
Varsayılan 151 değeri, orta ölçekli bir web sitesi için bile yetersiz kalabilir. Özellikle PHP uygulamalarında her sayfa yüklemesi potansiyel olarak yeni bir veritabanı bağlantısı açar.
2. Bağlantı Sızıntısı (Connection Leak)
Uygulamada veritabanı bağlantıları açılıp düzgün kapatılmıyorsa zamanla birikir. Bu durum özellikle try-catch bloklarında hata durumunda bağlantının kapatılmaması sonucu oluşur.
3. Persistent Connection Kötüye Kullanımı
PHP'de mysql_pconnect() veya PDO kalıcı bağlantılar kullanıldığında bağlantılar kapatılmaz ve havuzda birikir.
4. Kötü Optimize Edilmiş Sorgular
Uzun süre çalışan (long-running) sorgular bağlantıları meşgul tutar. Bu durum kısa sürede bağlantı limitine ulaşılmasına neden olur.
5. DDoS/Bot Saldırısı
Kötü niyetli trafik veya bot istekleri çok sayıda bağlantı oluşturabilir.
Mevcut Durumu Tespit Etme
SHOW PROCESSLIST ile Aktif Bağlantıları İnceleme
mysql -u root -p -e "SHOW PROCESSLIST;"
Bu komut aktif tüm bağlantıları listeler. "Sleep" durumundaki bağlantılar uyuyan bağlantılardır ve genellikle sorunun kaynağıdır.
# Uyuyan bağlantı sayısını say
mysql -u root -p -e "SHOW PROCESSLIST;" | grep -c Sleep
# Mevcut bağlantı sayısı
mysql -u root -p -e "SHOW STATUS LIKE 'Threads_connected';"
# Maksimum bağlantı değeri
mysql -u root -p -e "SHOW VARIABLES LIKE 'max_connections';"
# Tarihi maksimum bağlantı sayısı
mysql -u root -p -e "SHOW STATUS LIKE 'Max_used_connections';"
Çözüm 1: max_connections Değerini Artırma
Geçici Çözüm (Sunucu Yeniden Başlatma Gerekmez)
mysql -u root -p -e "SET GLOBAL max_connections = 500;"
Dikkat: Bu değişiklik MySQL yeniden başlatıldığında sıfırlanır.
Kalıcı Çözüm
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
# veya
sudo nano /etc/my.cnf
[mysqld]
max_connections = 500
wait_timeout = 60
interactive_timeout = 60
MySQL'i yeniden başlatın:
sudo systemctl restart mysql
Çözüm 2: wait_timeout ve interactive_timeout Ayarları
Uyuyan bağlantıların ne kadar süre tutulacağını belirler. Varsayılan değer 28800 saniye (8 saat)'tir. Bunu düşürmek uyuyan bağlantıları daha hızlı temizler:
[mysqld]
wait_timeout = 60
interactive_timeout = 60
max_allowed_packet = 64M
Çözüm 3: Bağlantı Havuzu Kullanma
PHP'de PDO ile Kalıcı Bağlantı
$pdo = new PDO(
"mysql:host=localhost;dbname=mydb;charset=utf8mb4",
"user",
"password",
[
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]
);
ProxySQL ile Bağlantı Havuzu
Yüksek trafikli uygulamalar için ProxySQL kullanmak ideal bir çözümdür. ProxySQL, uygulama ile MySQL arasında oturarak bağlantı havuzlaması yapar:
sudo apt install proxysql
sudo systemctl start proxysql
Çözüm 4: Uyuyan Bağlantıları Öldürme
Acil durumlarda uyuyan bağlantıları elle sonlandırabilirsiniz:
# Uyuyan tüm bağlantıları öldür
mysql -u root -p -e "
SELECT CONCAT('KILL ', id, ';')
FROM information_schema.processlist
WHERE command = 'Sleep' AND time > 60;" | mysql -u root -p
Çözüm 5: MySQL Performans Şeması ile Analiz
# En çok bağlantı açan kullanıcılar
mysql -u root -p -e "
SELECT user, host, COUNT(*) as connections
FROM information_schema.processlist
GROUP BY user, host
ORDER BY connections DESC;"
Doğru max_connections Değerini Hesaplama
Doğru değeri belirlemek için kullanılabilir RAM miktarına bakılır:
max_connections = Kullanılabilir RAM / (her bağlantı başı kullanılan RAM)
Her MySQL bağlantısı ortalama 0.5MB - 2MB RAM kullanır. Örneğin 4GB RAM'li bir sunucuda:
# MySQL için 2GB RAM ayırırsak
max_connections = 2000MB / 2MB = 1000
Ancak bu değer aşırı yüksek tutulursa sistem RAM'i tükenebilir. Gerçekçi bir değer seçin ve monitoring ile izleyin.
Önleyici Tedbirler
Monitoring
# Max_used_connections değerini izleyin
mysql -u root -p -e "SHOW STATUS LIKE 'Max_used_connections';"
# Bu değer max_connections'ın %80'ini geçtiyse artırma zamanı gelmiştir.
Slow Query Log Aktifleştirme
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
Uygulama Tarafında
- Veritabanı bağlantılarını her zaman try-finally bloğunda kapatın
- Gereksiz bağlantı açmaktan kaçının
- ORM seviyesinde lazy loading kullanın
- Sık kullanılan sorguları önbelleğe alın (Redis/Memcached)
Özet
MySQL Too Many Connections hatası, max_connections değerini artırarak, wait_timeout düşürerek ve bağlantı havuzu kullanarak çözülür. Ancak asıl çözüm uygulamanın bağlantı yönetimini optimize etmektir. SHOW PROCESSLIST ile durumu izleyin, slow query log ile sorunlu sorguları tespit edin ve uzun vadeli çözüm olarak ProxySQL gibi bir bağlantı havuzu aracı kullanmayı değerlendirin.
Yorumlar
Henüz yorum yok. İlk yorumu siz yapın!