PostgreSQL "canceling statement due to conflict with recovery" — Replica Neden Sorgu İptal Ediyor?
Replica'da sorguların "canceling statement due to conflict with recovery" ile kesilmesinin nedeni, pg_stat_database_conflicts ile teşhis ve üç farklı çözüm yolu.
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: canceling statement due to conflict with recovery
DETAIL: User query might have needed to see row versions that must be removed.Bu hata yalnızca replica'da (hot standby) görülür. Uzun süren bir SELECT çalışırken, primary'den gelen WAL kaydı o sorgunun okuduğu ölü satır sürümlerini temizlemek ister. Replica'nın iki seçeneği vardır: ya WAL replay'i geciktirir (replication lag) ya da sorguyu iptal eder. Varsayılan davranış, 30 saniye bekledikten sonra sorguyu iptal etmektir.
▸Nedeni ayırt eden sorgu
Replica üzerinde şu sorguyu çalıştırın:
SELECT datname,
confl_tablespace,
confl_lock,
confl_snapshot,
confl_bufferpin,
confl_deadlock
FROM pg_stat_database_conflicts
WHERE datname = current_database();- •`confl_snapshot` artıyorsa → Bu sayfadaki ana konu: satır sürümü çakışması (okunan ölü satırların WAL replay tarafından süpürülmesi).
- •`confl_lock` artıyorsa → Primary'de
ALTER TABLEveyaTRUNCATEyapılmış; gecikme parametreleri bunu engellemez. - •`confl_bufferpin` artıyorsa → Uzun süre tutulan buffer pin (nadir, genelde açık transaction).
confl_lock vakasında max_standby_streaming_delay'i yükseltmek hiçbir şeyi değiştirmez, çünkü kilit çakışması beklemez.▸Çözüm yolları (birini seçin, üçünü birden değil)
1. Sorguları süreyle sınırlayın (en sağlıklı başlangıç). Raporlama sorgularına üst sınır koyun:
SET statement_timeout = '120s';
-- veya rol bazlı kalıcı:
ALTER ROLE raporlama SET statement_timeout = '120s';Bu, çakışmayı ortadan kaldırmaz ama iptalin kontrolsüz değil, öngörülebilir olmasını sağlar.
2. Bekleme süresini artırın — bedelini bilerek.
ALTER SYSTEM SET max_standby_streaming_delay = '300s';
SELECT pg_reload_conf();Sorgular kesilmez, ama replica 5 dakikaya kadar geride kalabilir. Bu bir takas: rapor tutarlılığı karşılığında replikasyon tazeliği.
3. `hot_standby_feedback` açın — en çok yanlış anlaşılan ayar.
ALTER SYSTEM SET hot_standby_feedback = on;
SELECT pg_reload_conf();Replica, primary'ye "en eski ihtiyacım olan satır sürümü şu" bilgisini verir; primary de o noktaya kadar temizlik yapmaz. Sorgu iptalleri biter — ama primary'de bloat birikir. Uzun bir rapor sorgusu, primary'de milyonlarca ölü satırın temizlenmesini engelleyebilir. Autovacuum yetişemez, tablo şişer, disk büyür.
hot_standby_feedback yalnızca kısa sorguların olduğu replica'larda açılır. Analitik iş yükü ayrı bir replica'da çalışıyorsa, o replica'da kesinlikle kapalı tutulmalıdır.4. İş yükünü ayırın (kalıcı çözüm). Raporlama trafiğini, kullanıcıya hizmet eden canlı replica'dan ayırın. Ağır analitik sorgular kendi dedicated replica'sında çalışsın; oradaki iptaller kullanıcı deneyimini etkilemez.
▸Bunu bir daha yaşamamak için
pg_stat_database_conflicts tablosunu bir metrik olarak izleyin; confl_snapshot sıfır olmak zorunda değil, ama artan trend ya raporlama sorgularının uzadığını ya da primary'de temizliğin geri kaldığını gösterir. İkinci durum, autovacuum sorununa dönüşür ve çok daha pahalıdır. Ayrıca her replica için "burada hangi sorgular çalışabilir" kuralını yazılı hale getirin.
- •İlgili Runbook: PostgreSQL Replication Lag: Darboğazı Teşhis Etme
- •İlgili Hata: FATAL: sorry, too many clients already
Diğer Veritabanı Hata Teşhisleri
Kriz anında başvurabileceğiniz diğer doğrulanmış hata rehberleri.
PostgreSQL too many clients already Hatası: 6 Adımda Çözüm
FATAL: sorry, too many clients already hatasının üç nedeni, nedeni ayırt eden tek sorgu ve max_connections ile PgBouncer üzerinden kalıcı çö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.
MySQL ERROR 1045 Access denied: root Şifresi Sıfırlama Rehberi
MySQL 1045 hatasının dört nedeni, "using password: YES/NO" ayrımının anlamı ve kilitli kalınca --init-file ile güvenli şifre sıfırlama.