Postgresql Wal (Write-Ahead Logging)

Dünyaca ünlü bir DB ve adıda da tabi ki PostgreSql. O kadar çok detay, o kadar çok karmaşık ki bu DB tek başınıza öğrenmeye kalktığınızda zorlu bir süreç oluyor hele ki çalıştığınız yerde TB’larca data varsa ve onlarda işlemler yapmaya çalışıyorsanız daha çok korkutuyor bu DB bizi.

İşte benimde kabuslarımdan biri olan backup da streaming replication’da sürekli artan ve postgres’lerimize restart atmanızı sağlayacak şeyler yapan o WAL (Wtite-AHead Logging) hakkında öğrendiklerimi aktaracağım.

Nedir Bunlar ??

DB sisteminin veri bütünlüğü ve kayıplarını önlemek için kullandığı bir mekanizmadır. WAL ile DB’nizde yapılan değişiklikler ilk önce log dosyasına yazılır sonrasında ise DB’nize işlenir. Bu sayede değişikliklerin güvenli bir şekilde DB’ye yansıtıldığından emin oluruz.

Çalışma şeklinden bahsetmemiz gerekirse ise;

DB’nizde yapılan INSERT, UPDATE veya DELETE gibi işlemler ilk önce WAL günlüklerine yazılacak şekilde Önceliklendirilmiştir. Bu yapılan işlemler WAL’a yazıldıktan sonra Commit’lenir. Buda sisteminizde bir çökme olması durumunda işlemlerin WAL yardımıyla Güvenli bir şekilde kurtulabileceği anlamına gelir. Değişiklikler ilk olarak WAL’lara yazıldığı için yazma işlemi daha Performanslı hale gelir  ve DB’nizde gerçekleşen Checkpoint; işlemi ile birlikte işlemleri toplu olarak yapacaktır.

– WAL kullanımı sağlanması durumunda Recovery, Replikasyon ve Verimlilik konularında Fayda sağlayacaktır.

Ben genel olarak şuanda PostgreSql-13 kullandığımdan dolayı Wal dosyaların yeri aşağıdaki klasördedir.

> /var/lib/postgresql/13/main/pg_wal

Bu klasörün olduğu yeri psql komutları ile bulmak isterseniz ise;

> sudo psql -U postgres -c "SHOW data_directory;"
> cat /etc/postgresql/14/main/postgresql.conf | grep data_directory

– Şimdi ise bir WAL dosyasının adını nereden aldığına bakalım :

DB işlemlerini sıralamak ve takibinde kullanılan özel bir yapı ile isimlendirilirler. Bir WAL dosyası 24 karakter uzunluğunda bulunan bir Hexadecimal (OnAltılık) diziden oluşmaktadır. Bu dizeler 8’er şekilde dağılmaktadır.

ÖR : 000000010000000000000001

1. alanımız Timeline ID, DB’nin zaman çizelgesini temsil eder. Replication yapıları arasında veri karmaşasını önlemek için bazı durumlarda değişir. Pg_BaseBackup ve Pg_Rewind işlemleri sonrasında, DB’nizin Failover ya da Switchhover durumlarında yeni bir timeline başlatılacaktır.

2. alanımız ise Log Sequence Number (LSN) yani Log File ID’dir. WAL dosyaları için mantıksal bir sıra oluşturur. Genelde WAL’ların 16MB olarak tutulduğunu varsayarsak, bu boyut dolduğunda ve yeni WAL oluşturulduğunda değişecektir.

3. ise Segment ID’dir. Burasıda yine varsayılan olarak 16MB olan ama postgresql.conf dosyasından değiştirilebilen Size dolduğunda bir artacaktır.

Eğer Wal_Segment_Size ayarını değiştirmek istiyorsanız aşağıdaki adımları takip etmeniz gerekiyor.

İlk önce unutmayın kı Wal Size 1 2 4 8 16 …….. 1024 MB şeklinde ilerliyor. Bu değerlerden birini yapmanız gerekmektedir. İkincisi ise bu ayarı değiştirdiğinizde girmiş olduğunuz değerin 2 katı kadar postgresql.conf dosyasında bulunan min_wal_size değerine girmeniz şart.

Şimdi postgres kullanıcımıza geçiyoruz ve aşağıdaki adımları izliyoruz. Tabi ayrı bir terminal sayfasında da psql yaparak PostgreSQL’inize girin.

Psql > show wal_segment_size;
Psql> show wal_segment_size

Komutlarımız sayesinde wal_segment_size bilgisi alıyoruz.

Postgresql’imizi durduruyoruz ardından aşağıdaki komutu çalıştırıyoruz.

Postgres > /usr/lib/postgresql/13/bin/pg_resetwal -D /var/lib/postgresql/13/main --wal-segsize=64

Komutumuzu çalıştırdıktan sonra ise PostgreSql’imizi çalıştırıyoruz ve yukarıdaki görüntüleme komutlarını tekrar çalıştırarak farkı görüyoruz.

– Şimdi ise PostgreSql’imizin hangi WAL dosyaları ile uğraştığını bulmaya geldi sıra.

Psql > SELECT pg_current_wal_lsn();
Psql > SELECT pg_walfile_name(pg_current_wal_lsn());
Psql > SELECT pg_walfile_name('0/80002A8');
Psql > select pg_switch_wal();
Psql > SELECT pg_walfile_name(pg_current_wal_lsn());

1 – Komutumuz ile WAL Segment adını alırsınız.
2 – Komutumuz ile pg_wal dosyası altında bulunan adı alırsınız.
3 – WAL segment adını girerek Hexadecimal (OnAltılık) adını alırsınız.
4 – WAL dosyasının adını değiştirmek istiyorsanız bu komutu çalıştırırsınız.
5 – Bu komutlada WAL dosyasının adının değiştiğini görmüş olduk.

– Postgresql.conf içerisinde yapılan bazı değişiklikler ;

– Wal_level : Bu ayar sayesinde wal dosyalarının ayrıntı düzeyi belirlenir.

Minimal yazılması durumunda Veri Bütünlüğü için gerekli olan kısımları tutar. Replication ve PTIR için uyumlu değildir.

Replica yazılması durumunda Streaming Replication ve PITR için uyumlu hale gelecektir.

Logical yazıldığı zaman ise Logical Decoding ve Logical Replication için uyumlu olacaktır.

– Wal_buffers : WAL verilerinin diske yazılmadan önce kısa süreli olarak RAM’de tutulmasını sağlayan ayarımızdır. Varsayılan olarak shared_buffers’ın 1/32’si ve ya 16MB arasında hangisi küçük ise o atanır. Bu ayarlamayı KB cinsinden yaparız. Wal_Buffers’ı ne kadar yüksek olursa yoğun veri yazma sırasında performası artırır ancak RAM’in gereksiz yere kullanılmasınıda neden olabilir. Bu ayarı değiştirdikten sonra Postgresql’inize Restart atmanız gerekir.

ÖR : wal_buffers = 16MB

– Max_wal_size : PSQL tarafından diskte tutulacak WAL dosyalarının max toplam boyut değeridir. WAL dosyalarının toplam boyutu bu değeri aştığı zaman bir Checkpoint tetiklenir. Bu sayede WAL dosyaları temizlenir. Varsayılan olarak değeri ise 1GB’dır.

WAL boyutu archive_command, archive library, aşırı yük ya da wal_keep_size gibi parametrelerden dolayı artabilir.

ÖR : max_wal_size = 1GB

– Min_wal_size : PSQL tarafından diskte tutulacak WAL dosyalarının min toplam boyut değerini belirler. WAL dosyaları bu boyutun altında kaldığı sürece silinmezler. Varsayılan boyutu ise 128MB’dır.

ÖR : min_wal_size = 128MB

– Wal_compression : adından da anlaşıldığı gibi WAL dosyalarımızı sıkıştrır. Disk alanından tasarruf sağladığı gibi CPU kullanımını da artırabilir. Büyük veri yazma işlemlerinde tavsiye edilebilir. full_page_writes açıkken veya temel yedekleme sırasında WAL’a yazılan tam sayfa görüntülerini sıkıştırır. WAL yeniden oynatılmak istendiği zaman ise tekrar açılacaktır.

ÖR : wal_compression = off

– Checkpoint_timeout : Otomatik WAL kontrolleri arasındaki süreyi belirtir. Bu sayede WAL temizlemeleri otomatikleştirilir. Varsayılan değeri 5 dakikadır.

ÖR : checkpoint_timeout = 5min

– Checkpoint_completion_target : İşlemin ne kadar sürede tamamlanması gerektiğini belirten değerdir. Aldığı değer 0.0 ile 1.0 arasındadır. 0.0 yaparsanız hızlı bir şekilde bitirmeye çalışırken (sık ve yoğun disk yazımı), 1.0 yapmanız durumunda iki checkpoint arasındaki tüm süreye yayılır (Sürekli Disk yazımları).

ÖR : checkpoint_completion_target = 0.5

– Checkpoint_warning : Checkpoint’in planlanan zamandan önce tetiklenmesi durumunda uyarı mesajı üretilmesini sağlar.

ÖR : checkpoint_warning = 1min

– Full_page_writes : Çökme sırasında veri tutarlılığını sağlamak için kullanılan özelliktir. WAL’a yazılan verilerin artmasına ve disk’in daha fazla kullanılmasına sebep olacaktır ancak çökme durumlarında data kayıpları olmayacaktır.

ÖR : full_page_writes = on

– Synchronous_commit : Varsayılan olarak on’dur. PSQL’de yapılan veri değişiklikleri önce WAL’a yazılır ve istemciye işlemin tamamlandığına dair onay iletilir. Bu parametre on olarak ayarlandığında, WAL disk üzerine tam olarak yazıldığında ve senkronize olduğunda onay gönderilir. Replication olması durumunda ise en az bir standby sunucuna ulaştıktan sonra onay verecektir.
remote_apply olması durumunda synchronous replication kullanılıyorsa, standby sunucusuna uygulanması durumunda apply gönderilecektir. Remote_write ayarlanaması ise WAL dosyası standby sunucusuna ulaştığı zaman onaylanır. Local olması durumunda ise işlem ana sunucuda tamamlandığı zaman onaylanır. Off olması durumu ise dosya önbelleğe yazılır ve diske fiziksel olarak senk. edilmez.

ÖR : synchronous_commit = on

– Wal_writer_delay : WAL yazıcısının WAL’ı ne zaman temizleyeceğini zaman cinsinden belirtir. Varsayılan değeri 200ms’dir.

ÖR : wal_writer_delay = 200ms

– Wal_keep_size : Standby sunucularına teslim edilmemiş WAL dosyalarının saklanması için minimum boyutu belirler. Ayar ile replication’larınız koptuğu zaman eski WAL dosyalarının saklanacağı garanti altına alınır.

ÖR : wal_keep_size = 4000MB

– Archive_mode ve Archive_command : WAL’larımızı arşivlemek ve PSQL’imizi yedeklemek istediğimiz zaman açtığımız ayarlarımızdır. Ben bunu pgbackrest ile kullanıyorum o dökümanımı kontrol edebilirsiniz.

ÖR : archive_mode = on 
archive_command = ‘cp %p /var/lib/postgresql/archive/%f’

– Wal_receiver_status_interval : Standby sunucusunun ana sunucuya durumu bildirme sıklığını belirtir. Çok sık tutulması bant genişliği harcayabildiği gibi uzun tutulursada gecikme artabilir.

ÖR : wal_receiver_status_interval = 10s 

– Wal_writer_flush_after : WAL yazıcısının bellek tamponlarını ne zaman diske yazacağını belirtir.

Ör : wal_writer_flush_after = 1MB 

– Max_wal_senders : Aynı anda çalışabilecek Wal Sender süreçlerinin maksimum sayısını belirtiğimiz alandır. Streaming replication ve Wal arşivleme işlemleri sırasında kullanılırlar.

Ör : max_wal_senders = 10 

– Fsync : Postgresql tarafından OS’e yapılan fsync çağrısının anlamı, verilerin fiziksel olarak disklere aktarılıp, aktarılmadığını anlamaktır. Bu veri kayıplarını önleyen önemli bir özelliktir ve on durumunda olmalıdır.

Ör : fsync = on 

Bu yazımda bu kadar arkadaşlar umarım yararlı olur sizin için. Destekleriniz için SistemDostu youtube kanalıma beklerim sizleri arkadaşlar. Kolaylıklar dilerim.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir