VACUUM, dead tuple ların bulunduğu depolama alanını geri kazanır. Öncelikle Postgres üzerinde bir tabloda Update veya Delete çalıştırdığımızda neler olduğuyla başlayalım. DELETE işlemleri gerçekleştirildiğinde, verilerin bulunduğu tupleları fiziksel olarak silmek yerine mevcut tuple’ı DEAD olarak işaretler. Benzer şekilde, GÜNCELLEME işlemi gerçekleştirildiğinde, karşılık gelen mevcut tuple’ı DEAD olarak işaretler ve yeni bir tuple ekler.(Aslında Update = Hide/Unvisible + Insert demektir.)

Bu nedenle, her bir DELETE ve UPDATE komutu, asla kullanılmayacak olan bir DEAD tuple ile sonuçlanacaktır. Bu dead tuple lar, veriler aynı veya daha az sayıda olsa bile gereksiz fazladan alan kullanımına yol açacaktır.

İşte vacuum DEAD tuple ile ilgilenmeyi sağlayan bakım sürecidir. Vacuum işlemi sequential scan sırasında okunan tuple sayısını azaltacağı için okuma işlemlerinde de hızlanmaya sebep olacaktır. Sequential scan sıralı okuma işlemidir ve dead tuple’ları atlamaz. Dolayısı ile dead tuple’ların temizlenmesi daha az satır okunması anlamına gelir.

Vacuum, tüm tabloların taranmasını içerdiğinden, maliyetli bir işlemdir. 8.4 (2009) sürümünde, Visibility Map (VM), dead tupleların işaretlenme verimliliğini artırmak için tanıtıldı. 9.6 (2016) sürümünde, VM geliştirilerek freeze prosesi iyileştirildi.

Visibility Map

VM’in temel konsepti basittir. Her tablonun, tablo dosyasındaki her page’in görünürlüğünü tutan ayrı bir görünürlük haritası vardır. Pagelerin görünürlüğü, her page’de dead tuple olup olmadığını belirler. Vacuum, dead tuple içermeyen pageleri atlayabilir. Aşağıdaki şekildeki gibi bir tablomuz olduğunu düşünelim; Tablonun üç page’den oluştuğunu ve 0. ve 2. sayfaların dead tuplelar içerdiğini ve 1. sayfanın olmadığını varsayalım. Bu tablonun görünürüülük haritası(vm), hangi pagelerin dead tuplelar içerdiği hakkında bilgi içerir. Bu durumda, vacuum, VM’nin bilgilerine başvurarak 1. sayfayı atlar.

Postgresql Vacuum

Her VM bir veya daha fazla 8 KB page’den oluşur ve bu dosya ‘vm’ sonekiyle saklanır. Örnek olarak, FSM (18751_fsm) ve VM (18751_vm) dosyaları ile relfilenode 18751 olan bir tablo dosyası aşağıda gösterilmiştir.

 $ cd $PGDATA
$ ls -la base/16384/18751*
-rw------- 1 postgres postgres  8192 Apr 21 10:21 base/16384/18751
-rw------- 1 postgres postgres 24576 Apr 21 10:18 base/16384/18751_fsm
-rw------- 1 postgres postgres  8192 Apr 21 10:18 base/16384/18751_vm

Free Space Map

Free space map, her veri dosyasının boş alanı hakkındaki bilgileri depolar. Yukarıdada gördüğümüz gibi anadosyaya paralel ‘fsm’ soneki ile biten dosyada saklanır bilgiler. FSM’nin amacı yeterli alan içeren bir page’i hızlı bir şekilde bulmaktır veya böyle bir page’in bulunmadığını veri dosyasının bir page kadar büyütülmesi gerektiğini belirlemek içindir.

Freeze Tuple

Postgresql’deki her yazma işlemi veya bağımsız ifadeye benzersiz bir transaction id (veya XID) atanır. Bu XID, diğer eşzamanlı kullanıcıların transactionla ilişkili satır değişikliklerini görebileceğini belirleyerek öncelik görünürlüğünü(precedence visibility) belirler. Salt okunur işlemlere XID atanmaz. Bu XID’ler, depolamadaki her satıra xmin ve xmax biçiminde damgalanır ve satırı “görebilen” minimum ve maksimum eşzamanlı transactionları belirtir. Bunları row header lerine yerleştirerek, Postgresql’in eşzamanlılık(concurrency) yeteneklerini destekleyen transaction çakışması çözümünü merkezileştiriyor.

Ancak, XID’lerle ilgili bir sorun var: bunlar dört baytlık bir tamsayıdır. Bu, 2,1 milyar işlemden sonra başa sarmaları gerektiği anlamına gelir. Ve XID sayacı başa sardığında, eski XID’lerin tüm eski row headerlarından çıkarılması gerekir. Bu, XID’nin xmin ve xmax’tan kaldırılması ve özel RelFrozenXID değeriyle değiştirilmesi anlamına gelir; bu, herkesin görebileceği çok eski bir transactionı belirtir. (continue reading…)

Loading