WAL (Write Ahead Log)

Veri bütünlüğü için WAL standart bir metoddur.
Değişiklik memory’de yapılır, metadata bilgisi önce WAL dosyalarına yazılır.
Sonrasında en uygun zamanda bu dirty buffer, veri dosyalarına (data file) yazılır.
Dirty buffer diske yazılamadan elektrik/donanım vb. arızadan sistem kapanırsa (crash)
Memory deki dirty buffer kaybedilecektir.
Bu durumda postgresql, WAL dosyalarından, commit edilmiş tüm veriyi geri işleyecektir
(reapply). Böylece veri kaybı olmayacaktır.
Default boyutu 16MB’dır. İstenirse initdb parametresi –wal-segsize ile daha
büyük boyutlar verilebilir.
$PGDATA/pg_wal dizinine yazılır. Farklı bir diskte tutulması performans avantajı
sağlar. Bunun bir için parametre yoktur sembolik link ile yapılabilir.

  • Online yedek,
  • Sorunun olduğu son ana kadar verileri kurtabilme (completede recovery),
  • Point-in-time recovery yani hotbackup sonrası bir ana dönebilme,
  • Replikasyon (aktif – pasif cluster)
    Tüm bu özellikleri kullabilmek için WAL metoduna ihtiyaç vardır.
    Bu özelliklerden faydalanabilmek için arşivleme aktif edilmelidir. Yani wal dosyalarının
    bir kopyasını farklı bir ortama almak gerekir.

Current WAL (şu an yazılan ) dosyasınının tespiti

postgres=# SELECT pg_walfile_name(pg_current_wal_lsn());
pg_walfile_name
--------------------------
000000010000000000000006
postgres=# \! ls -ltr $PGDATA/pg_wal
postgres 6 Apr 13 10:20 archive_status
postgres 16777216 Apr 13 10:49 000000010000000000000007
postgres 16777216 Apr 13 10:49 000000010000000000000008
postgres 16777216 Apr 14 16:59 000000010000000000000009
postgres 16777216 Jul 14 16:32 000000010000000000000006

log switch (yeni WAL dosyasına geçiş)

select pg_switch_wal();

Saatlere WAL dağılımı

SELECT date_trunc('hour', modification) as hourly,
sum(size/1024/1024) as size_MB FROM pg_ls_waldir() GROUP BY
hourly ORDER BY hourly;

WAL dosyalarının saatlere göre dağılımı

select name, size/1024/1024 as size_MB, modification from pg_ls_waldir() order by 3 desc;

$PGDATA/pg_wal içeriği

select * from pg_ls_dir('pg_wal');

$PGDATA/pg_wal boyutu

select count(*) * 16 as total_size
from pg_ls_dir('pg_wal') as t(fname)
where fname <> 'archive_status';