dataiotech Labs
dbaguidedbaguideDBAdataxtoolsdataopsphere
Runbook #9
postgresql
LockingSEV2 · CİDDİ BOZULMA15-30 dakika / 15-30 minssuperuser / postgres / rds_superuser

PostgreSQL Deadlock İncelemesi

Deadlock sayaç ve loglarını birlikte okuyarak çakışan transaction ve nesneleri bulur; kilit sırası ve indeks tasarımıyla tekrarını önler.

İlişkili Metrik:M9
İlişkili Script:S2S17
#deadlock#40P01#log_lock_waits#foreign-key

Operasyonel Güvenlik ve Risk Uyarısı

Bu runbook müdahale adımları içerir; birçok adım yazma etkilidir (KILL, terminate, DROP, RESIZE). Önce test ortamında deneyin, üretimde adımları sırayla ve doğrulayarak uygulayın.

🟢 Salt Okunur (Read-Only)·🟡 Geri Alınabilir (Reversible)·🔴 Yüksek Etkili / Geri Alınamaz (High Impact)

1. Belirti / Symptom

- Uygulama SQLSTATE `40P01`, `deadlock detected` hatası alır; M9 deadlock sayacı artar.

- `pg_stat_database.deadlocks` zaman içinde artış gösterir (kümülatif sayaçtır).

2. Etki / Impact

PostgreSQL deadlock döngüsünü kırmak için transaction'lardan birini iptal eder; ilgili işlem retry etmezse kullanıcı işi başarısız olur. Çok sık döngü throughput'u düşürür.

3. Teşhis / Diagnosis

🟢 Salt Okunur1. Sayaç farkını ölçün:
sql
SELECT datname, deadlocks, stats_reset FROM pg_stat_database
WHERE datname = current_database();

İki zaman örneği arasındaki farkı alın; reset sonrası sayaç düşebilir.

🟢 Salt Okunur2. PostgreSQL logunda `deadlock detected` için `DETAIL: Process ... waits for ...; blocked by ...` ve `CONTEXT` satırlarını toplayın. Deadlock çözüldükten sonra S2 boş dönebilir: geçmiş döngü `pg_stat_activity` ile yeniden oluşturulamaz. `log_line_prefix` içinde PID ve transaction ID olduğundan emin olun.
🟢 Salt Okunur3. Etkilenen tablolar, transaction sırası, satır güncelleme sırası ve DDL/FK kontrolünü çıkarın. S17 FK sütunlarında destekleyici indeks bulunup bulunmadığını inceleyin. FK indeksi her zaman kök neden değildir; uygulama sorgusu ve planıyla doğrulayın.

4. Müdahale / Response

🟡 Geri Alınabilir1. Uygulamada yalnızca **SQLSTATE 40P01** için transaction'ın **tamamını** (tek statement değil) sınırlı sayıda, jitter'lı geri çekilme ile yeniden deneyin. İşlemlerin idempotent olduğunu doğrulayın.
🟡 Geri Alınabilir2. Çakışan kod yollarında tabloları ve satırları **her zaman aynı sırayla** kilitleyin, transaction'ları kısaltın. `SELECT ... FOR UPDATE` kullanıyorsanız sıralamayı uygulama düzeyinde tutarlı hale getirin.
🟡 Geri Alınabilir3. İhtiyaç duyulan FK indeksini iş yüküyle doğrulayıp uygun bakım penceresinde ekleyin:
sql
CREATE INDEX CONCURRENTLY idx_child_parent_id ON public.child (parent_id);

`CONCURRENTLY` transaction bloğu içinde çalıştırılamaz ve tamamlanmadan önce yeterli disk alanı gerekir.

🔴 YÜKSEK RİSK / GERİ ALINAMAZ4. **`deadlock_timeout` değerini körlemesine düşürmeyin veya artırmayın:** bu deadlock'un tespit/rapor hızını değiştirir, kök kilit döngüsünü çözmez. Yalnızca geçici tanılama gerekiyorsa `log_lock_waits = on` değerini kontrollü açın, log hacmini izleyin.

5. Doğrulama / Verification

- Bir tam trafik döngüsü boyunca M9 artışı durur; uygulama 40P01 hata ve retry metriği normalleşir.

- Test ortamında eşzamanlı çakışma senaryosu tekrar denenir.

6. Geri Alma / Rollback

- Yeni indeks yanlış plan oluşturduysa ilgili indeks bakım penceresinde `DROP INDEX CONCURRENTLY public.idx_child_parent_id;` ile kaldırılabilir; kilit ve plan etkisini doğrulayın.

- Log/timeout ayarlarını önceki değerlerine döndürün; iptal edilmiş transaction'lar otomatik geri gelmez.

Diğer POSTGRESQL Runbook'ları