top of page

WAL (Write-Ahead Logging) Nedir?

  • Yazarın fotoğrafı: Gökhan Dedeoğlu
    Gökhan Dedeoğlu
  • 1 gün önce
  • 4 dakikada okunur

Manyetik bantlardan devasa dönen disklere (HDD), oradan NVMe SSD’lere ve modern bulut depolama katmanlarına kadar her şey değişti. Ancak veri yönetiminin kalbindeki o temel soru hiç değişmedi: Bir elektrik kesintisi, donanım arızası veya işletim sistemi çökmesi anında, RAM’deki geçici (volatile) veriyi kaybetmeden diske en güvenli ve en hızlı şekilde nasıl yazarız?


İşte PostgreSQL’in (ve aslında modern tüm ilişkisel veritabanı yönetim sistemlerinin) bu soruya verdiği kusursuz yanıtın adı: WAL (Write-Ahead Logging), yani Önce Günlüğe Yazma.


Bu makalede, PostgreSQL’in veri güvenliğini ve yüksek erişilebilirlik (HA) mimarisini üzerine inşa ettiği WAL mekanizmasını, çekirdek seviyesindeki çalışma prensipleriyle derinlemesine inceliyoruz.


1. Temel Problem: Disk I/O Maliyeti ve ACID Güvencesi


İlişkisel bir veritabanı, ACID (Atomicity, Consistency, Isolation, Durability) prensiplerine uymak zorundadır. Özellikle Durability (Kalıcılık) ilkesi, istemciye “işleminiz başarılı” (COMMIT) yanıtı verildikten sonra, sistem çökse bile o verinin asla kaybolmamasını garanti eder.


Ancak bunu yaparken karşımıza çok ciddi bir performans engeli çıkar:

  • PostgreSQL’de veriler, disk üzerinde genellikle 8 KB’lık veri blokları (data pages) halinde saklanır.

  • Siz tek bir satırlık veriyi güncellediğinizde (UPDATE bakiye SET miktar = 100 WHERE id = 5), bu satır diskin bambaşka yerlerindeki veri bloklarında (tablo dosyası, ilişkili indeksler vb.) dağınık şekilde bulunabilir.

  • Eğer her COMMIT işleminde bu dağınık 8 KB'lık disk bloklarını doğrudan diske yazmaya (Random I/O) kalkarsak, disk kafası veya yazma kafası sürekli hareket etmek zorunda kalır. Bu da veritabanı performansının çökmesi demektir.


İşte WAL, bu performans ve güvenlik çelişkisini çözmek için geliştirilmiş muazzam bir akıllı çözümdür.


2. WAL Çalışma Prensibi: Sıralı (sequential) I/O Gücü


WAL’ın arkasındaki altın kural şudur: Veri bloklarında yapılan tüm değişikliklerin kaydı, asıl veri dosyaları güncellenmeden önce sıralı (sequential) bir günlük dosyasına yazılmalıdır.


Süreç adım adım şu şekilde işler:

  1. Shared Buffers (RAM): Bir INSERT/UPDATE/DELETE sorgusu geldiğinde, PostgreSQL önce hedef veri bloğunu diskten RAM'e (Shared Buffers) yükler ve değişikliği RAM üzerinde gerçekleştirir. Bu aşamada, RAM'deki bu bloğa Dirty Page (Kirli/Değiştirilmiş Sayfa) denir.

  2. WAL Buffers (RAM): Eş zamanlı olarak, bu değişikliğin ne olduğunu anlatan çok küçük, sıralı bir kayıt (WAL record) oluşturulur ve RAM’deki WAL Buffers alanına yazılır.

  3. Yazma ve COMMIT (Disk): İstemci işlemi onayladığında (COMMIT), PostgreSQL sadece ve sadece RAM'deki bu küçük WAL kaydını diske kalıcı olarak yazar. WAL dosyaları sıralı (sequential) olarak yazıldığı için disk bu işlemi milisaniyeler içinde (Random I/O'ya kıyasla yüzlerce kat daha hızlı) tamamlar.

  4. İstemci Onayı: WAL kaydı diske güvenli bir şekilde yazıldığı an (flush edildiğinde), istemciye “İşlem Başarılı” yanıtı döner. Asıl 8 KB’lık büyük veri dosyaları (Dirty Pages) hala RAM’dedir ve henüz diske yazılmamıştır!

Buradaki Güvence Nedir?Eğer tam bu anda sunucunun fişi çekilirse, RAM’deki veriler silinir. Ancak veritabanı yeniden açıldığında PostgreSQL, diske sıralı olarak yazılmış olan WAL kayıtlarını okur. “Bu işlem COMMIT edilmişti ama diskteki asıl veri dosyasına yansıtılmamıştı” der ve WAL’daki kayıtları veri dosyalarına yeniden uygular (REDO / Recovery süreci). Böylece sıfır veri kaybı sağlanır.

3. Kirli Sayfalar Diske Ne Zaman Yazılır? (Checkpointer ve Background Writer)


RAM’de biriken değiştirilmiş veri sayfalarının (Dirty Pages) sonsuza kadar orada kalması mümkün değildir. Bu sayfaların belirli aralıklarla diske kalıcı olarak işlenmesi gerekir. Bu işi üstlenen iki kritik PostgreSQL arka plan süreci (background worker) vardır:


Checkpointer

Belli aralıklarla (varsayılan olarak 5 dakikada bir veya belirli bir WAL boyutu aşıldığında) devreye giren en ağır süreçtir.

  • Görevi: RAM’deki tüm kirli (dirty) sayfaları tespit eder, bunları diske (asıl veri dosyalarına) yazar ve diske tamamen senkronize edildiğinden (fsync) emin olur.

  • Önemi: Checkpoint işlemi tamamlandıktan sonra, o noktadan önceki WAL kayıtlarına recovery (kurtarma) anında artık ihtiyaç kalmaz. Çünkü asıl veriler artık diske güvenle yazılmıştır. Bu durum, veritabanı çöktüğünde açılış süresini (RTO) kısaltır.


Background Writer (bgwriter)

Checkpointer gibi büyük bir temizlik operasyonu yapmak yerine, sürekli arka planda küçük adımlarla çalışır.

  • Görevi: RAM’de yeni gelen verilere yer açmak amacıyla, kirli sayfaları azar azar diske yazar. Böylece bir sorgu geldiğinde RAM’de hemen boş yer bulabilmesini sağlar.


4. WAL Konfigürasyonunun İnce Ayarları (Performance Tuning)


PostgreSQL performans darboğazlarının çok büyük bir kısmı hatalı WAL ayarlarından kaynaklanır. Sitenizde paylaşabileceğiniz, performans ve kararlılık için kritik postgresql.conf parametreleri şunlardır:

  • wal_level: WAL'a ne kadar detaylı bilgi yazılacağını belirler.

  • minimal: Sadece çökme kurtarma için yeterli bilgiyi yazar.

  • replica: (Varsayılan ve Önerilen) Replikasyon kurmak ve salt okunur standby sunucular yönetmek için gerekli tüm bilgiyi yazar.

  • logical: Mantıksal replikasyon yapacaksanız bu seviyeye getirmelisiniz.

  • max_wal_size ve min_wal_size: WAL dosyalarının diskte kaplayacağı maksimum ve minimum sınırları belirler. Modern, yoğun yazma alan sistemlerde max_wal_size değerini 1GB veya 2GB gibi varsayılan değerlerden 16GB - 32GB seviyelerine çekmek, gereksiz sık checkpoint tetiklenmesini önleyerek disk yazma yükünü (I/O spikes) muazzam ölçüde azaltır.

  • checkpoint_completion_target: Varsayılan olarak 0.9dur. Checkpoint yazma işleminin, bir sonraki checkpoint süresine yayılma oranını belirler. Disk I/O dalgalanmalarını engellemek için 0.9 değeri modern sistemlerde korunmalıdır.

  • synchronous_commit: Güvenlik ve performans arasındaki en büyük düğmedir.

  • on (Varsayılan): Her commit'te WAL'ın diske yazıldığından emin olunur (Güvenli).

  • off: Commit anında diske yazma beklenmez. Performansı uçurur ancak son 1-2 saniyelik verinin çökme anında kaybını göze almanız gerekir (Log toplama veya geçici veri sunucuları için harikadır).


5. Replikasyon ve WAL İlişkisi

WAL, sadece tek bir sunucunun çökmesini engellemekle kalmaz; PostgreSQL’in tüm

Yüksek Erişilebilirlik (HA) ekosisteminin yakıtıdır.

  • Fiziksel Replikasyonda: Primary sunucuda üretilen WAL dosyaları byte-by-byte (birebir) Standby sunucuya gönderilir. Standby sunucu, tıpkı çöken bir veritabanının kurtarma (recovery) modunda çalışması gibi, gelen bu WAL kayıtlarını sürekli “okuyup yazar” (continuous recovery).

  • Mantıksal Replikasyonda: WAL kayıtları gönderilmeden önce çözümlenir (Logical Decoding) ve SQL benzeri mantıksal DML komutlarına dönüştürülerek hedef veritabanına aktarılır.


Sonuç

PostgreSQL mimarisinde WAL, performanstan ödün vermeden veri bütünlüğünü koruyan bir mühendislik harikasıdır. Sıralı yazma hızı (Sequential I/O) sayesinde diskleri yormaz, sistem çökmelerinde koruyucu kalkan olur ve replikasyon mimarileri sayesinde kesintisiz sistemler kurmamızı sağlar.


WAL mekanizmasını iyi kavramak, Yüksek Erişilebilirlik serimizin sonraki adımlarında inceleyeceğimiz Patroni, etcd ve otomatik failover süreçlerindeki hata ayıklama (troubleshooting) yeteneğinizi doğrudan zirveye taşıyacaktır.

Yorumlar


GÖKHAN DEDEOĞLU

bottom of page