PostgreSQL'de VACUUM ve autovacuum: ölü satırlar, ayar ve izleme
PostgreSQL'de ölü satırlar, VACUUM ile VACUUM FULL farkı, autovacuum tetikleme formülü, tablo bazlı ayar, izleme sorguları ve işlem kimliği taşması riski.
VACUUM neden gerekir?
PostgreSQL, çok sürümlü eşzamanlılık denetimi (MVCC) kullanır. Bir satırı UPDATE ya da DELETE ettiğinizde eski satır sürümü hemen silinmez; çünkü başka işlemler hâlâ o sürümü görüyor olabilir. Bu eski sürümler "ölü satır" (dead tuple) olarak kalır ve hiçbir işlem artık onları görmediğinde yeniden kullanılabilir hale gelmesi için VACUUM'a ihtiyaç duyar.
PostgreSQL belgeleri, düzenli vacuum'un temel nedenlerini sayar: • Güncellenmiş veya silinmiş satırların kapladığı alanı geri kazanmak. • Sorgu planlayıcının kullandığı istatistikleri güncel tutmak (ANALYZE ile birlikte). • Görünürlük haritasını güncellemek; bu, yalnızca indeksten okuyan taramaların tabloya gitmeden çalışmasını sağlar. • İşlem kimliklerinin taşmasından (wraparound) kaynaklanan eski veri kaybını önlemek.
Bakım yapılmazsa ölü satırlar birikir, tablo ve indeksler gereğinden büyür (bloat), sorgular yavaşlar ve disk dolar. Çok sık güncellenen tablolarda sorun hızla belirir; hiç güncellenmeyen arşiv tablolarında ise daha az gözlenir.
VACUUM ile VACUUM FULL: temel fark
Sıradan VACUUM, ölü satırların yerini yeniden kullanıma hazır işaretler ama genellikle alanı işletim sistemine geri vermez. Çalışırken SELECT, INSERT, UPDATE ve DELETE'i engellemez. Belgeler, sık yapılan standart vacuum'u, seyrek yapılan VACUUM FULL'e tercih etmeyi önerir.
VACUUM FULL ise tabloyu baştan yazar ve alanı işletim sistemine iade eder. Bunun bedeli ağırdır: işlem sürerken tablo üzerinde en güçlü kilit tutulur, okuma ve yazma beklemek zorunda kalır; ayrıca geçici olarak tablo boyutu kadar ek disk gerekir ve işlem çok daha yavaştır.
Komut örnekleri:
VACUUM (VERBOSE, ANALYZE) siparis_log; VACUUM FULL siparis_log;
Birincisi rutin bakımdır; ikincisi ancak ciddi şişmiş bir tabloyu kurtarmak için bakım penceresinde yapılır. Belgeler, tabloyu yeniden yazan diğer işlemlerin (örneğin CLUSTER) de aynı ağır kilitle çalıştığını belirtir. Periyodik olarak tamamen boşaltılan tablolarda DELETE ve VACUUM yerine TRUNCATE tercih edilebilir; ancak TRUNCATE katı MVCC davranışını bozar, yani eşzamanlı işlemlerin görünürlüğü etkilenebilir.
Autovacuum nasıl çalışır?
Üretim kurulumlarında vacuum'u genellikle elle çalıştırmazsınız; autovacuum arka plan hizmeti bunu otomatik yapar. Hizmetin parçaları şunlardır: bir başlatıcı (launcher) ve işi yapan çalışanlar (workers). Başlatıcı, her veritabanı için belirli aralıklarla bir çalışan başlatmaya çalışır (autovacuum_naptime); aynı anda çalışan sayısı autovacuum_max_workers ile sınırlıdır. Çalışması için track_counts ayarı açık olmalıdır. Autovacuum hiçbir zaman VACUUM FULL çalıştırmaz.
Bir tablonun ne zaman vacuum'lanacağı, belgelerdeki formülle belirlenir. Sözle ifade edersek: eşik, taban eşik (autovacuum_vacuum_threshold) ile ölçek oranının (autovacuum_vacuum_scale_factor) tahmini satır sayısıyla çarpımının toplamıdır; bir üst sınır da (autovacuum_vacuum_max_threshold) uygulanır. Ölü satır sayısı bu eşiği aştığında tablo vacuum'lanır. Benzer biçimde ANALYZE için ayrı bir eşik ve ölçek oranı vardır. Yalnızca ekleme yapılan tablolar için de ayrı eklemeye dayalı bir eşik bulunur; bu, dondurma ve görünürlük haritası bakımını sağlar.
Bu formülün sonucu önemlidir: ölçek oranı, tablo büyüdükçe eşiği de büyütür. Çok büyük bir tabloda varsayılan oran, vacuum'un çok geç tetiklenmesine yol açabilir. Bu, büyük tablolarda ayar gerektiren en yaygın nedendir.
Belgeler ayrıca, autovacuum'un bölümlenmiş tabloları, yabancı tabloları ve geçici tabloları ANALYZE etmediğini belirtir; bunları elle analiz etmeniz gerekir.
Tablo bazında ayar: büyük ve sıcak tablolar
Genel ayarlar postgresql.conf dosyasından gelir; tablo bazında depolama parametreleri bunları o tablo için geçersiz kılar. Sık güncellenen büyük bir tabloda vacuum'u daha erken tetiklemek için ölçek oranını düşürebilirsiniz:
ALTER TABLE siparis_log SET ( autovacuum_vacuum_scale_factor = <küçük oran>, autovacuum_analyze_scale_factor = <küçük oran> );
Belirli bir ayarı genele döndürmek için:
ALTER TABLE siparis_log RESET (autovacuum_vacuum_scale_factor);
Ayar yaparken şu ilkeleri izleyin: • Önce ölçün, sonra değiştirin. Hangi tablolarda ölü satır birikiyor, autovacuum ne zaman çalışmış? • Küçük tabloya aşırı agresif ayar vermeyin; yalnızca gerçekten sorunlu büyük tabloları hedefleyin. • Giriş-çıkış baskısını ayarlayan maliyet parametrelerini (autovacuum_vacuum_cost_delay ve cost_limit) bilinçli kullanın: çok sıkı ayarlanan autovacuum, iş yükünü yavaşlatır; çok gevşek olan ise işi geç bitirir. Belgeler, birden fazla çalışan olduğunda bu parametrelerin aralarında dengelendiğini, tablo bazında ayar verilen tabloların dengelemenin dışında kaldığını belirtir. • Ayar değişikliğinden sonra birkaç gün izleyin; etkisini ölçmeden başka ayara geçmeyin.
Bir tabloda bir kez ağır bir toplu işlem yaptıysanız (büyük silme ya da güncelleme), sonrasında elle VACUUM (ANALYZE) çalıştırmak gerekebilir.
İzleme: ölü satır, son vacuum ve tutan işlemler
Vacuum'un çalışıp çalışmadığını görmek için istatistik görünümlerini kullanın. Bu görünümler PostgreSQL'in standart parçasıdır; sütun adlarını kendi sürümünüzün belgesinden doğrulayın:
SELECT relname, n_live_tup, n_dead_tup, last_autovacuum, last_autoanalyze FROM pg_stat_user_tables ORDER BY n_dead_tup DESC;
Bu sorgu, en çok ölü satır biriktiren tabloları ve autovacuum'un en son ne zaman çalıştığını gösterir. Ölü satır sayısı canlı satıra göre yüksekse ve son çalışma çok eskiyse, autovacuum ya o tabloya yetişemiyor ya da engelleniyordur.
Vacuum'un işini yapamamasının sık nedenleri: • Uzun süren açık işlemler: Eski satır sürümlerinin hâlâ görülebilir olması, vacuum'un onları temizlemesini engeller. Uzun süredir açık kalan işlemleri tespit edip nedenini giderin. • Hazırlanmış (prepared) işlemlerin unutulması. • Kullanılmayan çoğaltma yuvaları (replication slots); bunlar da eski verinin tutulmasına yol açar. • Autovacuum'un çalışanlarının çok az olması ya da maliyet sınırının çok kısıtlayıcı olması.
Belgelerdeki bir başka ipucu: log_autovacuum_min_duration ayarıyla autovacuum etkinliğini günlüğe yazdırabilirsiniz. Uzun süren vacuum'ları günlükte görmek, ayar kararlarını tahminden çıkarıp veriye dayandırır.
İşlem kimliği taşması (wraparound) ve dondurma
PostgreSQL, işlem kimliklerini sınırlı bir sayı aralığında tutar ve bunları dairesel olarak karşılaştırır. Çok eski bir satır sürümü, kimlikler döndüğünde "gelecekte" görünüp kaybolmuş sayılabilir. Bunu önlemek için vacuum, yeterince eski satır sürümlerini dondurur (freeze); dondurulmuş satır her zaman geçmişte kabul edilir. Belgelere göre her tablo, belirli bir işlem sayısı aşılmadan en az bir kez vacuum'lanmalıdır.
Bu yüzden autovacuum, tablonun en eski dondurulmamış işlem kimliği belirli bir yaşı (autovacuum_freeze_max_age) aştığında, ölü satır olmasa bile tabloyu zorunlu vacuum'lar. Bu, "taşmayı önleme" amaçlı vacuum olarak etkinlik görünümünde ayrıca işaretlenir ve diğer kilitlere yol vermez.
Taşma yaklaştığında sistem önce uyarı verir, sınıra çok yaklaşınca yeni işlem kimliği atamayı reddeder. Belgelerin önerdiği kurtarma sırası: eski hazırlanmış işlemleri çözmek, uzun süren işlemleri sonlandırmak, kullanılmayan çoğaltma yuvalarını silmek, ardından veritabanı genelinde standart VACUUM çalıştırmak (VACUUM FULL ya da VACUUM FREEZE değil). Bunu hiç yaşamamanın yolu, yaş izlemesini rutin hale getirmektir:
SELECT datname, age(datfrozenxid) FROM pg_database;
Bu değeri izleme sistemine bağlayın ve bir uyarı eşiği tanımlayın.
Bu beceriyi Mindset programlarında nerede çalışırsınız
"PostgreSQL İleri Seviye: Performans ve Yönetim" eğitiminin Mimari, MVCC ve Vacuum Yönetimi modülü bu sayfadaki konuyu temel mimariyle birlikte ele alır; Performans İzleme ve Sorun Teşhisi modülü de bu izleme becerisini sorun teşhisine taşır. Eğitim, üretim veritabanlarını yöneten DBA'ler, altyapı ve platform mühendisleri ile PostgreSQL üzerinde çalışan arka uç ekipleri için uygundur.
İlgili Mindset programı
PostgreSQL İleri Seviye: Performans ve Yönetim
Sık sorulan sorular
VACUUM FULL'ü ne zaman çalıştırmalıyım?
Yalnızca ciddi biçimde şişmiş ve alan iadesi gereken tablolarda, bakım penceresinde. VACUUM FULL tabloyu baştan yazar, güçlü kilit tutar ve geçici ek disk ister. Rutin bakım için standart VACUUM ve autovacuum yeterlidir; belgeler de sık standart vacuum'u önerir.
Autovacuum'u kapatmak mantıklı mıdır?
Hayır. Kapatmak ölü satırların ve dondurulmamış kayıtların birikmesine, sonunda performans düşüşüne ve işlem kimliği taşması riskine yol açar. Sorun yaşıyorsanız kapatmak yerine ayarını tablo bazında yapın ve neden yetişemediğini izleme verisiyle araştırın.
Ölü satır sayısı neden azalmıyor?
Genellikle uzun süren açık bir işlem, unutulmuş hazırlanmış işlem ya da kullanılmayan çoğaltma yuvası, eski satır sürümlerinin temizlenmesini engeller. Önce bu tutucuları bulup giderin; ardından autovacuum'un o tabloya yetişip yetişmediğini ve maliyet sınırının kısıtlayıp kısıtlamadığını kontrol edin.
ANALYZE ile VACUUM aynı şey mi?
Hayır. ANALYZE, planlayıcının kullandığı istatistikleri günceller; VACUUM ölü satırları temizler ve görünürlük haritasını işler. VACUUM (ANALYZE) ikisini birlikte yapar. Autovacuum da ikisini ayrı eşiklerle tetikler. Büyük bir toplu yüklemeden sonra ANALYZE çalıştırmak plan kalitesi için önemlidir.
Büyük tabloda autovacuum neden geç tetikleniyor?
Eşik, ölçek oranının tahmini satır sayısıyla çarpımına bağlı olduğundan tablo büyüdükçe eşik de büyür; varsayılan oran çok büyük tabloda vacuum'u geciktirebilir. Çözüm, o tabloya özel daha küçük bir ölçek oranı tanımlamaktır. Bunu yapmadan önce izlemeyle ölü satır birikimini doğrulayın.
İlgili rehberler
Kategori: Veri Mühendisliği ve MLOps, Yazılım Geliştirme