PostgreSQL VACUUM'un Sayfa Düzeyinde Byte Byte İncelemesi
PostgreSQL VACUUM'un üç aşamalı çalışma mekanizması pageinspect, pg_visibility ve pg_freespacemap ile sayfa düzeyinde analiz edildi. LP_DEAD ve LP_UNUSED farkı netleşiyor.
Bu içerik, PostgreSQL'in VACUUM işleminin sayfa düzeyinde tam olarak ne yaptığını pageinspect, pg_visibility ve pg_freespacemap araçlarıyla önce-sonra karşılaştırmalı olarak gösteriyor. Sıradan okumalar sırasında çalışan HOT pruning'in aksine, VACUUM indeksli sütunlardaki soğuk güncellemeler, DELETE işlemleri, indeks temizliği, free space map ve visibility map bakımı gibi pruning'in yapamadığı her şeyi kapsıyor. Makale, DELETE sonrası bir satırın t_xmax değeri güncellenirken sayfa üzerinde tek byte'ın bile geri kazanılmadığını somut örneklerle gösteriyor.
Asıl teknik derinlik VACUUM'un üç fazlı çalışma modelinde: Faz 1 heap taraması yapıp ölü tuple'ları budar, pd_upper'ı ilerletir ve uygun tuple'ları dondurur; ancak indeksli tablolarda ölü satırların line pointer'ı LP_UNUSED yerine LP_DEAD olarak işaretlenir çünkü indeksler hâlâ o TID'e işaret etmektedir. Faz 2'de her indeks taranarak ölü TID'lere işaret eden girdiler temizlenir — bu en maliyetli aşamadır ve uzun süren transaction'lar ya da bellek sınırları burada indeks şişmesine yol açabilir. Faz 3'te ise artık hiçbir indeks referans vermediği için LP_DEAD pointer'lar nihayet LP_UNUSED'a çevrilerek slot serbest bırakılır ve visibility map bit'i güncellenir.
PostgreSQL 17 ile birlikte ölü TID'lerin tutulduğu düz dizi yapısı yerine radix tree tabanlı bir depolama getirildi; bu da maintenance_work_mem'in darboğaz olma ihtimalini büyük ölçüde azaltıyor. İndeksi olmayan tablolarda ise bu üç fazlı ayrım tamamen ortadan kalkıyor: tek geçişte ölü pointer'lar doğrudan LP_UNUSED'a çevrilebiliyor. Bu detaylar, VACUUM tuning'i yapan veya index bloat sorunlarıyla uğraşan mühendisler için VACUUM'un neden bazen beklenenden yavaş kaldığını veya indeks şişmesine yol açtığını anlamada kritik önem taşıyor.