Hafıza (Memory) Yapısı


I/O hem de OIPS performanslarını karşılaştırdığımızda RAM, SSD diskten defalarca kat
daha hızlıdır. Manyetik diskler de SSD disklerden yavaştır.
Performans için I/O işlemleri mümkün olduğunca hafıza (memory) üzerinde yapılmak
istenir.
Postgresql’ de hafıza alanlarının (memory structure) farklı kullanım amaçları ve
yöntemleri vardır.
Örneğin; Bir alan (memory structure) kod tutmak için kullanılırken, diğer bir alan veri
bloklarını tutmak için kullanılır.

Bazı hafıza alanları (memory) tüm kullanıcılar için paylaşımlı iken diğer bir alan
kullanıcıya özeldir.

Shared Memory (Paylaşımlı alan); Postgresql instance’ ı açıldığında kendisi için ayırılan
hafızayı (memory) sistemden alır.
Alacağı hafıza (memory) miktarı shared_buffer, wall_buffer vb.
parametrelerle belirlenir. Bu alanlardan bir kısmı da kendi içinde alt bölümlere ayrılır.
Paylaşımlı hafıza alanları (shared memory structure) tüm kullanıcılarla ve backend
proseslerle paylaşımlı olarak kullanılır.

Per Backend Memory (Local Memory Area); SQL sorgu işlemleri için kullanılır.
Her backend proses kendi kullanımı için bu hafıza alanını sistemden alır.
Paylaşımlı değildir. Kendi içinde alt bölümlere ayrılır.

Sistemden (session sayısı) * (Backend Memory) miktarında hafıza (memory) alacaktır.
Yani session sayısını ve Backend memory alanlarını hesaplarken dikkat edilmesi gerekir.
İleriki konularda detay bulabilirsiniz.

RAM : Random Access Memory
I/O : Okuma yazma
IOPS : Input/output operations per second : Saniyede gerçekleştirilebilen işlem sayısı.
(1 GB’lık bir imaj dosyasını kopyalamak ile içerisinde 10240 adet 1 KB lık dosya olan
klasörü kopyalama hızları farklıdır.)

Shared Memory

Shared Buffer

alter system set shared_buffers ='24GB';

  • Paylaşımlıdır. Veri bloklarını bulundurur.
  • OS Cache ile entegre çalışır.
    Shared buffer alanı tüm kullanıcılar ve background prosesler tarafından paylaşımlı
    olarak kullanılır.
  • Default değeri 128MB’dır.
  • shared_buffers’ ı ayarlarken birim (MB, GB) verilmezse, verilen rakamı blok sayısı
    olarak algılar ve blok boyutu (size) ile çarparak KB cinsinden konfigurasyonu yapar.

Örnek: alter system set shared_buffers=100;
Burada block size 8KB (default değer) olduğundan için shared_buffers=800KB
değerini atar.
shared_buffers’da yapılan değişikliğin geçerlilik kazanması için instance’ ı kapatıp
açmak gerekir.

Shared buffer için önerilen değer sistemdeki RAM’ in 1/4’ü kadardır.
Bazı yük tiplerinde Shared Buffer’a RAM’ in %40’ a kadar hafıza atanabilir lakin
Postgresql, işletim sisteminin ön belleğiyle de (OS Cache) entegre çalıştığından,
%40’tan fazla hafızanın (memory) performansa olumlu etki edeceği anlamına gelmez.

Shared Buffer artırıldığında, değişiklik yapılmış (update/delete) ve/veya yeni
(insert) veri boyutu da artacaktır (DML kapasitesi artacatır). Bunların diske
yazılma işlemlerini, daha uzun zamana yayabilmek için max_wal_size değeri de
artırılmalıdır.
Not: İşletim sisteminin kernel ayarlarına bağımlılığı vardır. Eğer değişiklik sırasında
istediğiniz değerleri verirken hata alıyorsanız işletim sistemizin kernel ayarları ile ilgili
olabilir.

Buffer cache kullanımı ile ilgili detaylı bilgi için pg_buffercache extension’ı
yüklenebilir.

Shared Buffer ve OS Cache


Bir sorgu geldiğinde;

  1. Backend proses önce shared buffer’ı kontrol eder eğer burada bulunursa logical I/O
    gerçekleşir.
  2. Eğer buffer cache’ te yok ise OS cache’ e bakılır. Eğer OS cache’te bulunur ise gene
    logical I/O gerçekleşir.
  3. Eğer OS cache’te de yok ise istenen bloklar diskten okunur ve fiziksel I/O
    gerçekleşmiş olur ki fiziksel I/O nun maliyeti yüksektir.

Hafızanın (memory) büyük bir bölümünü buffer cache’e verip de OS cache göz ardı
etmek gibi bir seçeneği Postgresql’de yapmak istemezsiniz zira başka bir noktada
performansı düşürecektir.
İki cache alanının da amacı üzerinde yoğun I/O olan veriyi hafızada (memory) tutup
mümkün olduğunca disk üzerindeki I/O işlemlerini azaltmaktır.

Commit log bilgilerinin tutulduğu pg_xact (9.6 öncesi pg_clog ) klasöründe
sürekli okuma yazma işlemleri gerçekleştirilir. Bu yüzden işletim sistemi pg_xact
klasöründeki dosyaları hafızada (OS Cache) tutmak ister. Bu durumda OS cache
miktarını yüksek tutmak da performansa katkı sağlar.

Postgresql hafıza (shared buffer) yönetiminde OS Cache’ten daha iyidir. Postgresql,
işlem sıklığına göre bloklara 0-5 aralığında değerler verir. Fazla işlem gören bloklara
yüksek değer, işlem sayısı az olan bloklara ise düşük değer verir. Hafızada yer açmak
gerektiğinde ise değeri düşük olan bloklar hafızadan çıkarılır. Bu çalışma şekline clock sweep algoritması denilir.

OS Cache algoritma olarak genelde LRU’un (Least Recently Used) çeşitli formlarını
kullanır. Hafızada (cache) tutulacak bloklara bir ya da iki şans tanınır. Detaylı bir analize girmez. Bu yüzden Postgresql’in hafıza (shared buffer) yönetimi OS Cache‘ten daha iyidir.

WAL Buffer

alter system set wal_buffer = '64MB' ;

  • Paylaşımlıdır, veritabanında yapılan değişikliklerin kaydını tutar.
  • DML ve DDL ile yapılan değişiklikleri yeniden yapılabilmesi için gerekli olan bilgiyi tutar.
  • Postgresql, veri tutarlılığını sağlamak için gerekli olan Write Ahead Log (WAL)
    mekanizmasını destekler.
  • WAL (transaction log) veritabanında yapılan değişiklilerin metadata bilgisini tutar.
    Gerektiğinde buradaki kayıtları kullanarak veriyi yeniden oluşturur (REDO) ya da
    modifiye eder.
  • WAL mekanizması sistem hatalarında (crash, elektrik kesintisi, donanımsal arıza vs.) dahi commit edilmiş veriyi diske işler (rollforward), commit edilmemiş veriyi de geri alarak (rollback) veri kaybına ve tutarsızlığa engel olur.
  • WAL Buffer diske henüz yazılmamış WAL verisinin geçici olarak tutulduğu buffer alandır.
  • Paylaşımlıdır, tüm background server ve backend prosesleri tarafından erişilebilir.
  • Her commit işleminde WAL buffer alanındaki veri, diske yazılır. MB seviyesinde artışlar bile performans artışı sağlayabilir.
  • Default değeri “-1” dir. Bu otomatik ayarlama anlamına gelir, shared_buffers’ ın 32’de birini alır (shared_buffers/32).
    Örneğin; shared_buffers=512MB ise wal_buffer=16MB değerini alır
    .
  • 64KB’den düşük, WAL segment boyutundan büyük olamaz.
  • Statik bir parametredir, değişikliğin aktif olması için instance’ı kapatıp açmak gerekir.

NOT: WAL mekanizmasının sağlıklı çalışabilmesi için sisteminizin ve veritabanınızın en iyi yapılandırma (best practice) kurallarına göre ayarlanması gerekir.

Clog Buffer


  • Commit loglarının tutulduğu paylaşımlı hafıza (memory) alanıdır. Bir transaction ının 4 statüsü vardır. Commit log bu statüleri tutar:
    • in_progress
    • committed
    • aborted
    • sub_committed
  • Bütün background server ve backend prosesler tarafından erişilebilir.
    Eşzamanlı erişim mekanizmasının (Concurrency Control Mechanism) bir parçasıdır.
  • Boyutunu değiştirebilecek bir parametre bulunmamakla birlikte ilk kurulum sırasında
    kaynak koddan derleyerek (CLOGShmemBuffers()) ya da yama (patch) ile artırılabilir.
  • pg_xact dizinine yazar (10 versiyonundan önce -> pg_clog).

Lock Space


  • Paylaşımlıdır. Doğrudan değiştirilebilecek bir parametresi yoktur.
  • Ortalamadan fazla olan kilitlerin (lock) saklandığı hafıza (memory) alanıdır. Bu kilit (lock) background ve backend user prosesleri tarafından paylaşılır.
  • max_locks_per_transaction ve max_pred_locks_per_transaction parametrelerindeki değişiklik lock space’i de etkiler.

Per Backend Memory

Work Memory


  • Paylaşımlı değildir, her oturumun (session) kendi hafıza alanı vardır.
  • Sıralama (sort) order by, distinct, merge joins ve hash tablo operasyonları için kullanılır.
    work_mem alanı yeterli olmazsa diskteki temporary dosyalara yazar (fiziksel I/O).
  • Her oturum (session) ve proses kendi özel alanını kullanır. Basit bir hesapla, oturum (session) sayısı * work_mem alanı kadar sistemden hafıza (memory) alır.
    work_mem default değeri 4MB’dir. Instance’ınızda 300 oturum (session) varsa 4MB * 300 = 1200MB = 1GB memory işletim sisteminizden alır (shared_buffers’dan almaz).
  • Kompleks sorgularda birkaç sort ve hash operasyonu paralel çalışabilir, bu operasyonların her biri kendisi için ayrı ayrı work_mem alanı tahsis edebilir.
# Sistem genelinde değiştirmek için;
alter system set work_mem= '16MB';

# Mevcut oturumun work_mem değerini değiştirmek için ;
set local work_mem = 128MB;

# Postgres 13 sürümündeki bug dolayısıyla bu ayar hata verir, aşağıdaki şekilde çalıştırılabilir;
set local work_mem = 102400\;

# Belirli bir kullanıcı veya role özel work_mem ayarı yapmak için;
alter user mehmed set work_mem= '256MB';

  • Hash temelli operasyonlar, sıralama (sort) operasyonlarına oranla daha fazla hafızaya (memory) ihtiyaç duyarlar.
    Hash tablo işlemlerinde hash_mem_multiplier parametresindeki değer ile
    work_mem değeri çarpılarak, kullanılabilecek hafıza (memory) miktarı hesaplanır.
    Bu nedenle hash temelli işlemler standart work_mem miktarından fazlasını kullanabilir.
  • work_mem parametresinin default birimi KB’dir. Değer atarken birim belirtilmezse KB cinsinden değer atar.

Temp Memory


# Sistem genelinde değiştirmek için;
alter system set set temp_buffers= '16MB';

# Mevcut oturumun temp_buffers değerini değiştirmek için ;
set local temp_buffers = 128MB;

# Postgres 13 sürümündeki bug'dan dolayı bu ayar hata verir. Aşağıdaki şekilde hata vermiyor.
set local temp_buffers = 102400\;

# Belirli bir kullanıcı veya role özel temp_buffers ayarı yapmak için;
alter user mehmed set temp_buffers='256MB';
  • Temp tabloları için kullanılan buffer alanıdır. Paylaşımlı değildir. Her oturumun (session) kendi temp buffer alanı vardır.
    temp_buffers her bir oturumun (session) maksimum kullanabileceği temp buffer alanını belirler.
  • Default değer 8MB dir.
  • Değiştirirken birim (unit) verilmezse blok boyutuyla (block size) çarparak yeni değeri hesaplar.
  • Parametrede verilen hafıza (memory) miktarını oturum (session) başlar başlamaz rezerve etmez.
  • Büyük değerler verilse bile ihtiyaç duyulduğunda kullanılan bir alandır. Oturum (session) bazlı değişiklik yapılabilir.

Maintenance Work Memory

alter system set maintenance_work_mem= '128MB';

  • Bakım işlemleri için kullanılan hafıza alanıdır.
    Vacuum, create index, alter table add foreign key vb. bakım ve onarım (maintenance) işlemleri için kullanılabilecek hafızanın (memory) üst limitini belirler.
  • Default değer 64 MB’dir.
    Birim (unit) verilmeden değiştirilirse default birimi kilobyte’dır.
  • Bir oturum (session) sadece bir adet bakım işlemi (maintenance tasks) çalıştırır.
    Bu yüzden work_mem değerinden çok daha fazlası verilebilir. Böylece vacuum
    ve dump,restore işlemlerinin performansı arttırılmış olur.
  • Autovacuum işlemi çalışırken autovacuum_max_workers katına kadar hafızayı alabilir.
  • autovacuum_max_workers default değeri 3’tür, arttırırken dikkatli olmakta fayda var.

Catalog Cache


  • Sistem tablolarınının tutulduğu hafıza alanıdır.
  • Sistem tablolarındaki şema, tablo, view, index vb. objelerle ilgili bilgileri bulundurur.
  • Çoğu işlemde katalog bilgilerine ihtiyaç vardır. Örneğin select cümlesindeki tablo,
    gerçekten var mı, kolon var mı, çalıştıran kişinin hakkı var mı vb. bir çok bilgiye sistem
    katalogdan erişilir.
    Bu verileri her seferinde diskten okumak performans dar boğazlarına
    neden olacağından catalog cache’te tutulur.

Autovacuum Work Mem

alter system set autovacuum_work_mem = '128MB';

  • Her bir autovacuum worker prosesinin kullanabileceği maximum hafıza (memory) miktarını belirler.
  • Birim (unit) verilmeden değiştirilirse default birim olarak KB alır.
  • Default değeri “-1” dir. Bu durumda maintenance_work_mem ile aynı değeri alır.
  • Autovacuum, dead tuple tanımlayıcılarını toplarken maximum 1 GB hafıza (memory) kullanabilir. Bu yüzden 1GB’den daha fazla değer vermenin bir etkisi olmayacaktır.
Kategori seçin...