POSTGRESQL PERFORMANS VE VACUUM
Yüksek yazma trafiği olan bir PostgreSQL sunucusunda iki yol vardır: autovacuum'u varsayılan eşiklerle bırakıp "kendi kendini halleder" demek ya da bakım pencerelerinde manuel VACUUM ve ANALYZE ile devreye girmek. İlk seçenek kolaydır; ikincisi disiplin ister. Üretim ortamında çoğu ekip, sorgu süreleri yavaşlamaya başlayana kadar bu iki yol arasındaki gerçek farkı görmez — ve fark genellikle tablo şişmesi (bloat) olarak kendini gösterir.
Autovacuum Varsayılanları Neyi Vaat Eder, Neyi Etmez
PostgreSQL'in autovacuum_vacuum_scale_factor değeri varsayılan olarak 0.2'dir; yani bir tablonun %20'si "ölü tuple" oranına ulaşana kadar autovacuum tetiklenmez. 10 milyon satırlık bir tabloda bu, 2 milyon ölü satır demektir. Eşik düşük tablolar için makul, büyük tablolar için ise çoğu zaman çok geç.
autovacuum_naptime 1 dakika, autovacuum_max_workers 3'tür. Aynı anda 50 tablonun bakıma ihtiyacı varsa, sıraya girer ve bazıları saatler boyunca beklemek zorunda kalır. Üretimde yaygın gözlenen tablo:
- n_dead_tup > n_live_tup oranıyla şişmiş tablolar
- Index-only scan için
visibility map'in eski kalması pg_stat_user_tables.last_autoanalyzedeğerinin günler öncesini göstermesi- Sorgu planlayıcısının yanlış istatistiklerle sequential scan seçmesi
Manuel VACUUM/ANALYZE'ın Devreye Girdiği Senaryolar
Bazı yük profilleri autovacuum'un tasarımıyla örtüşmez. Toplu UPDATE veya DELETE sonrası bir kerede milyonlarca satır ölür; varsayılan eşik bu satırları görmezden gelir çünkü işlem öncesi tablo zaten büyüktür. Burada manuel müdahale şarttır:
- Toplu silme/güncelleme sonrası
VACUUM (VERBOSE, ANALYZE) tablo_adi; - Veri yükleme sonrası
ANALYZEile istatistik tazeleme - Index şişmesi için
REINDEX CONCURRENTLY - Saatlik raporlama tablolarında zamanlanmış bakım pencereleri

Tablo Bazlı Override: Ortak Cevap Burada
Cevap genellikle "autovacuum mu manuel mi" değil, "hangi tablo için ne ayar" sorusudur. PostgreSQL bunu tablo başına override etmenize izin verir:
ALTER TABLE siparisler SET (autovacuum_vacuum_scale_factor = 0.02, autovacuum_analyze_scale_factor = 0.01);
Bu, sık güncellenen büyük tablolar için autovacuum'u global ayarları değiştirmeden agresifleştirir. Append-only log tabloları için ise autovacuum_vacuum_insert_scale_factor ile ekleme bazlı bakım tanımlanabilir. Parametrelerin tam listesi ve davranış detayları için resmi rutin vacuum dokümantasyonu başvuru noktası olarak kullanılabilir. PostgreSQL'in iç işleyişine ve performans ayarlarına derinlemesine hakim olmak için PostgreSQL eğitimi içeriğinden yararlanabilirsiniz.
Üretim Ortamı Ölçümleri: Gerçek Sonuçlar
Bir OLTP sisteminde 30 milyon satırlık islemler tablosunda gözlenen tipik tablo:
- Varsayılan autovacuum: Tablo boyutu 18 GB → 41 GB (bloat ~%55), index scan sürelerinde 3-4x yavaşlama
- Override edilmiş autovacuum (scale_factor 0.02): Tablo boyutu 21 GB civarında stabilize, bloat %12 altında
- Sadece haftalık manuel VACUUM: Pencere arasında bloat birikiyor, sorgu süreleri dalgalı seyir izliyor
Sonuç net: tablo başına agresifleştirilmiş autovacuum, çoğu üretim yükünde haftalık manuel VACUUM'dan daha tutarlı performans verir. Manuel VACUUM, autovacuum'un yerine değil tamamlayıcısı olarak konumlanmalıdır — özellikle toplu işlemler sonrası ve VACUUM FREEZE ile transaction ID wraparound önlemleri için.
İzleme: Ne Ölçmediğinizi Bilemezsiniz
VACUUM stratejisi izleme olmadan tahmindir. pg_stat_user_tables, pg_stat_progress_vacuum ve pg_stat_activity birlikte okunmalıdır. İzlenmesi gereken minimum metrik seti:
n_dead_tup / n_live_tuporanı (tablo bazında, %20 üstü alarm)last_autovacuumvelast_autoanalyzezaman damgalarıautovacuum_counttrendinin günlük değişimiage(relfrozenxid)— wraparound için kritik- Bloat tahmini için
pgstattupleuzantısı veyacheck_postgresçıktısı

Bakım Penceresi mi, Sürekli Bakım mı?
Eski Oracle alışkanlığıyla gelen ekipler "haftalık bakım penceresi" düşünür. PostgreSQL felsefesi tersinedir: bakım sürekli ve küçük adımlarla yapılmalıdır. autovacuum_vacuum_cost_limit ve autovacuum_vacuum_cost_delay parametreleri tam bunun içindir — I/O bütçesini sınırlayarak bakımı görünmez kılmak. PostgreSQL 12 sonrası cost_delay varsayılanı 2 ms'ye düşürüldü; eski sürümlerden gelen 20 ms ayarıyla çalışan sistemlerde autovacuum'un neden "yetişemediği" çoğu zaman bu tek satırda gizlidir. PostgreSQL ile performans yönetimi pratiklerini farklı senaryolarda görmek için PostgreSQL eğitimi sayfasını inceleyebilirsiniz.
Pratik özet: varsayılan autovacuum çoğu üretim yükü için yetersizdir, ama tamamen manuel bakım da sürdürülebilir değildir. Doğru cevap; tablo başına agresif autovacuum override'ları + toplu işlem sonrası nokta atışı manuel VACUUM ANALYZE + bloat ve wraparound metriklerinin sürekli izlenmesidir. Bu üçü birlikte çalıştığında, bakım artık bir "pencere" değil, sistemin sessiz bir alt katmanı haline gelir.



