Önce şunu ayırın: bağlantı mı, kilit mi, sorgu mu?
Too many connections hatası görüldüğünde max_connections değerini artırmak çok cazip gelir. Bazen gerçekten gerekir; ama çoğu zaman yalnızca semptomu büyüteçten uzaklaştırır. Uygulama havuzu çok büyükse, her yayına alma veya worker artışı veritabanına yeni baskı üretir.
Kilit beklemeleri ise bağlantı sayısını dolaylı artırır. Bir transaction uzun süre açık kalırsa diğer istekler bekler, bekleyen istekler de connection pool içinde yer tutar. Yani kilit sorunu bir süre sonra bağlantı sorunu gibi görünmeye başlar.
Anlık bağlantı ve bekleme kontrolü
SHOW FULL PROCESSLIST; SELECT event_name, count_star, sum_timer_wait FROM performance_schema.events_waits_summary_global_by_event_name WHERE event_name LIKE 'wait/lock/%' ORDER BY sum_timer_wait DESC LIMIT 10;
Kilit bekleyen sorguyu netleştirin
MySQL’de yavaşlık bazen sorgunun kötü planından değil, başka bir transaction tarafından tutulmasından kaynaklanır. Bu durumda EXPLAIN tek başına yeterli değildir; bekleyen ve bloklayan transaction ilişkisini görmek gerekir.
Özellikle ödeme, stok veya sipariş güncelleyen sistemlerde uzun transactionlar bağlantı havuzunu hızla tüketir. Uygulama tarafında transaction süresi kısa tutulmalı, kullanıcıdan cevap bekleyen işlem transaction içinde bırakılmamalıdır.
InnoDB transaction ve lock bekleme kontrolü
SELECT trx_id, trx_state, trx_started, trx_wait_started, trx_mysql_thread_id, trx_query FROM information_schema.innodb_trx ORDER BY trx_started; SELECT * FROM performance_schema.data_lock_waits LIMIT 20;
EXPLAIN ile yavaş sorgu okuma
MySQL EXPLAIN çıktısında type=ALL büyük tablolarda tam taramaya işaret edebilir. rows alanı çok yüksekse ve filtered düşükse, sorgu doğru indeksi kullanmıyor olabilir.
Composite index sırası WHERE ve ORDER BY kullanımına göre seçilmelidir. Sadece tek kolon indeksleri eklemek her zaman optimizer için en iyi planı üretmez.
Plan ve indeks örneği
EXPLAIN FORMAT=JSON SELECT id, status, created_at FROM orders WHERE tenant_id = ? AND status = 'paid' ORDER BY created_at DESC LIMIT 50; CREATE INDEX idx_orders_tenant_status_created ON orders (tenant_id, status, created_at DESC);
Pool ve zaman aşımı ayarını uygulama davranışıyla eşleştirin
Too many connections gördüğünüzde max_connections artırmak son çare olmalıdır. Önce uygulama pool limitini, connection acquire zaman aşımı değerini ve retry davranışını kontrol edin. Agresif retry, kısa süreli bir yavaşlığı bağlantı fırtınasına çevirebilir.
TürkDB MySQL tarafında bağlantı ve PITR gibi operasyonlar görünür hale gelir; ancak uygulama aynı anda yüzlerce gereksiz bağlantı açıyorsa bu davranış kod tarafında düzeltilmelidir.
Uygulama pool ayarı örneği
const pool = mysql.createPool({
uri: process.env.MYSQL_DSN,
waitForConnections: true,
connectionLimit: 20,
queueLimit: 100,
connectTimeout: 5000,
})PITR ile değişiklik riskini azaltın
İndeks, migration veya veri düzeltme operasyonları öncesinde kurtarma penceresini görmek kritik bir alışkanlıktır. TürkDB’de MySQL için PITR penceresi ve geri yükleme işlemi CLI üzerinden kontrol edilebilir.
MySQL cluster ve PITR kontrolü
turkdb cluster create --name commerce-mysql \ --type mysql \ --version 8.0 \ --plan standard \ --region ist1 \ --wait turkdb cluster pitr window commerce-mysql turkdb cluster pitr restore commerce-mysql \ --to "2026-06-14T09:30:00Z" \ --name commerce-mysql-restore