dataiotech Labs
dbaguidedbaguideDBAdataxtoolsdataopsphere
Home/PostgreSQL/Hata Kodları (Errors)/postgresql-conflict-with-recovery
[Teşhis]PostgreSQL PG 14 - 17Advanced
6 dk okuma

PostgreSQL conflict with recovery Hatası: hot_standby_feedback

PostgreSQL "canceling statement due to conflict with recovery" — Replica Neden Sorgu İptal Ediyor?

Yazar / Standart:Kıdemli Veritabanı Mimarı & SRE (dataiotech Labs)
ERROR: canceling statement due to conflict with recovery
İlk 60 Saniye Teşhis Protokolü:

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

plaintext
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:

sql
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 TABLE veya TRUNCATE yapılmış; gecikme parametreleri bunu engellemez.
  • •`confl_bufferpin` artıyorsa → Uzun süre tutulan buffer pin (nadir, genelde açık transaction).
[!IMPORTANT] Bu ayrım kritiktir: 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:

sql
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.

sql
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.

sql
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.

[!WARNING] 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.

PostgreSQL Diğer Üretim Rehberleri

Aynı veritabanı motoruna ait doğrulanmış diğer içerikler.

Tümünü Gör