pg_dump ile uğraşmayı bıraktığım gün, sistem yazılım mühendisi olarak ciddiyetimin arttığını düşünüyorum. pg_dump bir araştırma aracı — production yedek aracı değil.
Üretim yedeği üç şeyi sağlamalı:
- Point-in-time recovery (PITR). “Dün gece 02:13’te silindi” diyebilmek.
- Bütünlük doğrulaması. Yedek dosyasının açıldığında çalıştığını test etmek.
- Saklamayı politikayla yönetmek. Saatlik/günlük/haftalık/aylık rotasyon.
pg_dump üç maddeyi de karşılamıyor.
pgBackRest kurulum
Ben hem yerel hem de s3 yedeği almayı tercih ve tavsiye ediyorum. Yerel yedekler hızlı, S3 yedekleri ise yangına dayanıklı.
Off-Site Copy
Repository tek bir diskte duruyorsa bir VPS yangını her şeyi siler. pgBackRest S3 veya S3-uyumlu (R2, MinIO) bucketa yazabiliyor:
Tercih: bucket versiyon-kilitli ve delete’i yasaklayan bir policy ile koruyun. Ransomware senaryosunda kritik.
Maliyetleri uzun vadeli kontrol altında tutmak için bucket yaşam döngüsünü ayarlayın:
30 Gün → Glacier Anında Alma → 120 Gün → Sil
/etc/pgbackrest.conf:
[global]
###################################
# Local Repository
###################################
repo1-path=/var/lib/pgbackrest
repo1-retention-full=4
repo1-retention-diff=14
repo1-cipher-pass=...
repo1-cipher-type=aes-256-cbc
###################################
# AWS S3 Repository
###################################
repo2-type=s3
repo2-path=/main
repo2-s3-bucket=...
repo2-s3-endpoint=s3.{region_name}.amazonaws.com
repo2-s3-region={region_name}
repo2-s3-key=...
repo2-s3-key-secret=...
repo2-cipher-type=aes-256-cbc
repo2-cipher-pass=...
###################################
compress-type=zst
compress-level=6
process-max=4
start-fast=y
log-level-console=info
log-level-file=detail
log-path=/var/log/pgbackrest
[main]
pg1-path=/var/lib/postgresql/16/main
pg1-port=5432
Yetkileri sıkılaştır;
sudo chown postgres:postgres /etc/pgbackrest.conf
sudo chmod 640 /etc/pgbackrest.conf
Stanza oluştur:
sudo -u postgres pgbackrest --stanza=main stanza-create
postgresql.conf tarafında ise WAL archiving’i pgBackRest’e yönlendiriyoruz:
archive_mode = on
archive_command = 'pgbackrest --stanza=main archive-push %p'
archive_timeout = 60
wal_level = replica
archive_timeout = 60 — son 60 saniyenin işlemleri kaybedilebilir; çoğu uygulama için yeterli, finansal işlemler için değil.
Backup planı
Cron tarafından:
0 2 * * 0 pgbackrest --stanza=main --type=full backup
0 2 * * 1-6 pgbackrest --stanza=main --type=diff backup
0 */6 * * * pgbackrest --stanza=main --type=incr backup
Haftalık full, günlük diff, 6 saatlik incremental. Storage tüketimi şaşırtıcı derecede düşük — pgBackRest delta block tekniği ile değişen sayfaları tespit ediyor.
Bütünlük: yedek varsa restore edilebilir mi?
Yedeği almak yeterli değil. Haftada bir restore tatbikatı:
pgbackrest --stanza=main --delta restore --pg1-path=/tmp/pg_restore_test
Sonra o instance’ı geçici bir port üzerinde başlatıp birkaç sanity query çalıştırıyorum. Bu adım atlanırsa yedek sahte güven olur.
PITR provası
Belirli bir zamana geri dönmek:
pgbackrest --stanza=main \
--type=time \
--target='2026-05-07 02:13:00+03' \
restore
Bu komutun gerçek bir incidentte ilk kez çalıştırılması felakettir. Provayı önceden yapın — adımlar runbook’a yazılsın.
Saklama
Repository’deki kullanılmayan yedeklerin temizliği expire komutuyla:
pgbackrest --stanza=main expire
repo1-retention-full=4 ile son 4 full yedek tutuluyor; daha eskileri (ve onlara bağlı diff/incr’ler) otomatik temizleniyor.
Sonuç
pg_dump ile schema kopyalamak veya küçük bir tabloyu taşımak hâlâ doğru araç. Ama PITR isteyen herhangi bir sistemde yedek yazılımı pgBackRest (veya barman, ya da veritabanı sağlayıcının yerli aracı) olmalı. Backup’ın test edilmediği anda “backup’ım var” demek yalan söylemenin sofistike bir yoludur.