PostgreSQL "deadlock detected" — Hangi İki İşlem Birbirini Kilitledi?
PostgreSQL deadlock hatasında bloklayan oturumları pg_blocking_pids ile bulma, log_lock_waits ayarı ve erişim sırası düzeltmesi.
Operasyonel Doğrulama & Güvenilirlik Standardı
Hata mesajı semptomdur, kök neden değildir. Sunucuyu yeniden başlatmadan veya rastgele ayar değiştirmeden önce aşağıdaki "Nedeni ayırt eden tek sorgu"yu çalıştırarak gerçek senaryoyu netleştirin.
▸Belirti
ERROR: deadlock detected
DETAIL: Process 4821 waits for ShareLock on transaction 9102; blocked by process 9102.
Process 9102 waits for ShareLock on transaction 4821; blocked by process 4821.
HINT: See server log for query details.PostgreSQL döngüsel kilitlenmeyi (Wait-For Graph) tespit ettiğinde işlemlerden birini kurban seçerek anında iptal eder (SQLSTATE 40P01). Bu kontrol deadlock_timeout (varsayılan 1 saniye) süresi dolmadan tetiklenmez; yani 1 saniyeden kısa süren kilit beklemeleri deadlock kontrolüne takılmaz.
▸Blokaj Zincirini ve Kök Oturumu Bulma
PostgreSQL'in bu iş için yerleşik fonksiyonu vardır:
SELECT pid,
pg_blocking_pids(pid) AS bloklayanlar,
state,
now() - query_start AS suredir,
left(query, 100) AS sorgu
FROM pg_stat_activity
WHERE cardinality(pg_blocking_pids(pid)) > 0
ORDER BY suredir DESC;bloklayanlar dizisinde yer alan ve kendi bloklayanlar hücresi boş olan oturum kilit ağacının tepesindeki kök nedendir.
Kilit beklemelerini kalıcı kayıt altına almak için:
ALTER SYSTEM SET log_lock_waits = on;
SELECT pg_reload_conf();Artık deadlock_timeout süresini aşan her kilit beklemesi deadlock oluşmasa dahi sunucu günlüğüne kaydedilir.
▸En Sık Üç Kök Neden
1. Ters Tablo Erişim Sırası
- •İşlem A:
hesaptablosunu kilitler →harekettablosunu bekler. - •İşlem B:
harekettablosunu kilitler →hesaptablosunu bekler.
Çözüm: Tüm uygulama kodlarında tabloların her zaman alfabetik veya hiyerarşik aynı sırayla kilitlenmesini sağlayın.
2. Yabancı Anahtar (Foreign Key) Kontrolleri
PostgreSQL'de FK kontrolleri ebeveyn satır üzerinde FOR KEY SHARE kilidi alır. İki eşzamanlı işlem farklı tablolara yazarken birbirlerinin ebeveyn satırlarını güncelliyorsa kilitlenme veritabanı motoru katmanında tetiklenir.
3. Toplu Güncellemelerde Rastgele Satır Sıralaması
-- YANLIŞ: IN listesi deterministik sırada kilitlenmez
UPDATE hesap SET bakiye = bakiye - 10 WHERE id IN (42, 17, 99);
-- DOĞRU: Sıralı ve deterministik kilit edinimi
UPDATE hesap SET bakiye = bakiye - 10
WHERE id IN (SELECT unnest(ARRAY[42, 17, 99]) ORDER BY 1);▸Uygulama Tarafında Yeniden Deneme (Retry) Politikası
Deadlock kurbanı işlem tamamen geri alınır; uygulama katmanında bu durum standart bir akış olarak ele alınmalıdır:
- •Yalnızca
40P01(deadlock) ve55P03(lock not available) kodları yeniden denenmelidir. - •İşlem mutlaka idempotent olmalıdır.
- •Üstel geri çekilme (exponential backoff) ve rastgele gecikme (jitter) kullanılmalıdır.
deadlock_timeout değerini yükseltmeyin; yükseltmek tespiti geciktirir ve tüm oturumların kuyrukta beklemesine yol açar.- •Kardeş Hata (MySQL): MySQL Error 1213: Deadlock found when trying to get lock
- •Kardeş Hata (SQL Server): SQL Server Error 1205: Deadlock Victim
- •İlgili Hata: SQL Server Error 1222: Lock request time out period exceeded
- •Veritabanı Hub: PostgreSQL Üretim Mimarisi Rehberi
Diğer Veritabanı Hata Teşhisleri
Kriz anında başvurabileceğiniz diğer doğrulanmış hata rehberleri.
PostgreSQL Bağlantı Tükenmesi ve too many clients Teşhisi
FATAL: sorry, too many clients already ve remaining connection slots hatalarının üç temel kök nedeni, yetki sınırlarıyla salt okunur pg_stat_activity teşhisi ve kalıcı iki katmanlı havuzlama çözümü.
PostgreSQL password authentication failed Hatası: Neden ve Çözüm
psql password authentication failed hatasının dört nedeni: yanlış şifre, md5/SCRAM uyuşmazlığı, pg_hba.conf sırası ve yanlış cluster. Adım adım teşhis.
PostgreSQL connection refused: 8 Adımda Kesin Teşhis
Connection refused, timeout ve "no pg_hba.conf entry" arasındaki fark; listen_addresses, port, firewall ve Docker port yayınlama kontrolleri.