PostgreSQL Lock Chain and Blocking: Find and Resolve the Root Blocker
Finds the session at the head of a lock chain and resolves it safely. Covers the DDL queue trap and prevention methods.
Operational Safety & Risk Notice
This runbook contains operational intervention steps; several are write-impacting (KILL, terminate, DROP, RESIZE). Verify in a staging environment first, and apply sequentially in production with verification.
1. Symptom & Signals
- Sorgular uzun süre bekliyor, uygulamada zaman aşımı.
- `pg_stat_activity` içinde `wait_event_type = 'Lock'` olan çok sayıda oturum.
- M8 (kilit bekleyen oturum) eşiği aşıldı.
2. Business & Technical Impact
Etkilenen tablolara okuma/yazma gecikir veya durur. Zincir uzadıkça bağlantı havuzu dolar ve `pg-too-many-connections` senaryosuna dönüşebilir.
3. Diagnosis & Root-Cause Analysis
SELECT blocked.pid AS blocked_pid, left(blocked.query,100) AS blocked_query,
blocker.pid AS blocking_pid, blocker.state AS blocking_state,
left(blocker.query,100) AS blocking_query,
now() - blocker.xact_start AS blocker_tx_age
FROM pg_stat_activity blocked
JOIN LATERAL unnest(pg_blocking_pids(blocked.pid)) AS b(pid) ON true
JOIN pg_stat_activity blocker ON blocker.pid = b.pid;- `idle in transaction`: uygulama transaction'ı açık unutmuş. En sık neden.
- `active` ve uzun: ağır bir DDL veya toplu güncelleme çalışıyor.
- `ALTER TABLE` bekliyor olabilir (aşağıdaki tuzağa bakın).
SELECT l.pid, l.locktype, l.mode, l.granted, l.relation::regclass
FROM pg_locks l WHERE NOT l.granted OR l.pid = <kok_pid>;4. Remediation & Action Plan
SELECT pg_cancel_backend(<kok_pid>);SELECT pg_terminate_backend(<kok_pid>);3. Sonlandırmadan önce **sorgu sahibini** (`usename`, `application_name`) ve işin kritikliğini kontrol edin. Veri taşıma veya fatura kesimi gibi işleri körlemesine kesmeyin.
4. **DDL kuyruğu tuzağı:** Uzun bir okuma transaction'ı varken `ALTER TABLE` gelirse, DDL `ACCESS EXCLUSIVE` kilidini bekler ve **arkasından gelen tüm basit SELECT'ler de DDL'in arkasında kuyruğa girer.** Çözüm: bekleyen DDL'i iptal edin (`pg_cancel_backend`), tüm tablo trafiği normale döner.
5. **Önleme:**
-- Migration oturumunda:
SET lock_timeout = '3s';
SET statement_timeout = '5min';
-- Genel güvenlik ağı:
ALTER SYSTEM SET idle_in_transaction_session_timeout = '5min';Migration'larda `CREATE INDEX CONCURRENTLY` ve kısa transaction kullanın.
5. Verification & Health Checks
- Adım 1 sorgusu boş dönüyor, M8 normale döndü.
- Bekleyen uygulama sorguları tamamlandı, hata oranı düştü.
- Kök nedenin (açık kalan transaction, uygulama hatası, migration) kaydı tutuldu.
6. Rollback & Contingency Plan
- `pg_cancel_backend` ve `pg_terminate_backend` geri alınamaz; ilgili işlem rollback olur ve uygulama tarafından yeniden denenmelidir.
- `lock_timeout` değişikliği oturum bazlıysa oturum kapanınca kendiliğinden kalkar.