Deadlock nedir? Veritabanında nasıl oluşur ve nasıl önlenir?
Cevap
Deadlock, iki (veya daha fazla) transaction'ın birbirinin tuttuğu kilidi beklemesi ve hiçbirinin ilerleyememesidir.
Örnek
-- Transaction A -- Transaction B
BEGIN; BEGIN;
UPDATE hesaplar SET ... WHERE id = 1; UPDATE hesaplar SET ... WHERE id = 2;
-- id=1 kilitli -- id=2 kilitli
UPDATE hesaplar SET ... WHERE id = 2; UPDATE hesaplar SET ... WHERE id = 1;
-- B'yi bekler -- A'yı bekler -> DEADLOCKPara transferinde A, 1'den 2'ye; B ise 2'den 1'e aynı anda gönderim yaparsa tam olarak bu olur.
Veritabanı ne yapar?
PostgreSQL ve MySQL bekleme grafiğinde döngü tespit eder ve transaction'lardan birini kurban seçip iptal eder (PostgreSQL: deadlock detected, MySQL: error 1213). Diğeri devam eder. Uygulama iptal edilen transaction'ı yeniden denemelidir.
Önleme yöntemleri
- Kilitleri her zaman aynı sırada alın. Transfer örneğinde önce küçük ID'li hesabı kilitleyin:
SELECT * FROM hesaplar WHERE id IN (1, 2) ORDER BY id FOR UPDATE;- Transaction'ları kısa tutun; transaction içinde HTTP çağrısı veya kullanıcı beklemesi yapmayın.
- Doğru index kullanın; index olmadan
UPDATE ... WHEREgereğinden fazla satırı (veya gap'i) kilitleyebilir. - Gerekenden yüksek isolation level kullanmayın.
lock_timeoutile sonsuza kadar beklemeyi engelleyin;NOWAITveyaSKIP LOCKEDile alternatif akış kurun (iş kuyruğu tablolarındaSKIP LOCKEDçok kullanılır).
Tespit
PostgreSQL'de log_lock_waits = on ve log'lardaki deadlock detayları; MySQL'de SHOW ENGINE INNODB STATUS son deadlock'u gösterir.
İlgili Veritabanı & SQL soruları
Bu konuda başka bir soru biliyor musun?
Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.