Blog
PostgreSQLVeritabanıYedeklemeReplikasyonDevOps

PostgreSQL Yedekleme ve Eş Zamanlı Replikasyon: pg_basebackup, WAL Arşivleme ve Streaming Replication

16 Haziran 2026 · 12 dk okuma

"Yedek alıyoruz" ile "yedekten dönebiliyoruz" arasında dağlar kadar fark var. Birçok kurum, bir kriz anında yedeklerinin bozuk veya eksik olduğunu fark eder — o zaman iş işten geçmiş olur.

PostgreSQL, sağlam bir yedekleme altyapısı için ihtiyacınız olan her şeyi sunar. Bu yazıda üç katmanlı bir strateji kuruyoruz: anlık yedek, sürekli WAL arşivleme ve gerçek zamanlı standby.

Yedekleme Stratejisinin Üç Katmanı

KatmanYöntemRPORTO
1. Anlık yedekpg_basebackupSaatlerDakikalar-saatler
2. Sürekli arşivWAL arşivleme + base backupDakikalarDakikalar
3. Canlı standbyStreaming replicationSaniyelerSaniyeler

RPO (Recovery Point Objective): Ne kadar veri kaybedebilirsiniz?
RTO (Recovery Time Objective): Ne kadar sürede ayağa kalkmalısınız?


Katman 1: pg_basebackup ile Anlık Yedek

En basit yöntem. Tüm cluster dosyalarını kopyalar.

# Temel kullanım — sıkıştırılmış tar arşivi
pg_basebackup \
  --host=localhost \
  --username=replicator \
  --pgdata=/yedek/pg_base_$(date +%Y%m%d) \
  --format=tar \
  --compress=9 \
  --checkpoint=fast \
  --progress

# Cron ile günlük yedek (her gece 02:00)
0 2 * * * pg_basebackup -h localhost -U replicator \
  -D /yedek/pg_$(date +\%Y\%m\%d) -Ft -z -Xstream -P

Replikasyon kullanıcısı oluştur

CREATE USER replicator REPLICATION LOGIN ENCRYPTED PASSWORD 'güçlü_şifre';

pg_hba.conf'a ekle:

host  replication  replicator  127.0.0.1/32  scram-sha-256

Yedekten Dönme Testi

Almak kadar dönmek de önemli — her yedek test edilmeli.

# Test ortamına geri yükle
mkdir -p /test/pg_restore
tar -xzf /yedek/pg_20260616/base.tar.gz -C /test/pg_restore

# PostgreSQL'i test portta başlat
postgres -D /test/pg_restore -p 5433 &

# Bağlan ve kontrol et
psql -p 5433 -c "SELECT count(*) FROM kritik_tablo;"

Katman 2: WAL Arşivleme — Dakika Düzeyinde Kurtarma

WAL (Write-Ahead Log), PostgreSQL'in tüm değişiklikleri önce yazdığı günlüktür. Bu dosyaları arşivleyerek herhangi bir dakikaya dönebilirsiniz (Point-in-Time Recovery — PITR).

postgresql.conf Ayarları

wal_level = replica          # en az replica olmalı
archive_mode = on
archive_command = 'cp %p /wal-arsiv/%f'  # ya da rsync, s3 vb.
archive_timeout = 300        # 5 dakikada bir arşivle (boşta bile)

Daha güvenli bir archive_command (başarısız olursa yeniden dener):

archive_command = 'test ! -f /wal-arsiv/%f && cp %p /wal-arsiv/%f'

Uzak sunucuya rsync ile:

archive_command = 'rsync -a %p yedek-sunucu:/wal-arsiv/%f'

PITR — Belirli Bir Zamana Dönme

Diyelim ki saat 14:32'de bir tablo yanlışlıkla silindi. Tam o ana dönebilirsiniz:

# 1. Son base backup'ı restore et
tar -xzf /yedek/pg_20260616/base.tar.gz -C /data/pg_restore

# 2. recovery.conf (PG 12 öncesi) veya postgresql.conf'a ekle
cat >> /data/pg_restore/postgresql.conf << 'EOF'
restore_command = 'cp /wal-arsiv/%f %p'
recovery_target_time = '2026-06-16 14:31:59'
recovery_target_action = 'promote'
EOF

# 3. recovery.signal dosyası oluştur (PG 12+)
touch /data/pg_restore/recovery.signal

# 4. Başlat
pg_ctl start -D /data/pg_restore

PostgreSQL WAL dosyalarını sırayla uygulayarak tam olarak 14:31:59'daki duruma getirir.


Katman 3: Streaming Replication — Sıfıra Yakın Veri Kaybı

Primary → Standby arasında gerçek zamanlı veri akışı. Primary çökerse standby saniyeler içinde devreye girer.

Primary Ayarları (postgresql.conf)

wal_level = replica
max_wal_senders = 3          # aynı anda kaç standby bağlanabilir
wal_keep_size = 1GB          # standby geride kalırsa buffer
hot_standby = on             # standby read-only sorguları kabul etsin
synchronous_commit = on      # senkron replikasyon (veri kaybı sıfır, biraz daha yavaş)

pg_hba.conf'a standby izni:

host  replication  replicator  STANDBY_IP/32  scram-sha-256

Standby Kurulumu

# Primary'den base backup al
pg_basebackup \
  --host=PRIMARY_IP \
  --username=replicator \
  --pgdata=/data/standby \
  --wal-method=stream \
  --progress

# Standby sinyali
touch /data/standby/standby.signal

# postgresql.conf'ta primary bağlantısı
echo "primary_conninfo = 'host=PRIMARY_IP user=replicator password=şifre'" \
  >> /data/standby/postgresql.conf

# Başlat
pg_ctl start -D /data/standby

Replikasyon Durumunu İzle

-- Primary'de: standby'lar bağlı mı, geride mi?
SELECT
    application_name,
    state,
    sent_lsn,
    replay_lsn,
    (sent_lsn - replay_lsn)::text AS gerideki_bytes,
    sync_state
FROM pg_stat_replication;

-- Standby'da: ne kadar geride?
SELECT
    now() - pg_last_xact_replay_timestamp() AS replikasyon_gecikmesi;

Failover — Standby'ı Promote Et

Primary çöktüğünde:

# Standby'ı primary olarak yükselt
pg_ctl promote -D /data/standby

# Ya da SQL ile
SELECT pg_promote();

Uygulama bağlantılarını yeni primary'ye (eski standby) yönlendirin.


Sektördeki En İyi Araçlar

AraçKullanımÜcreti
BarmanMerkezi WAL arşivleme, çoklu cluster yönetimiÜcretsiz
pgBackRestParalel yedek, S3 entegrasyonu, delta backupÜcretsiz
repmgrOtomatik failover yönetimiÜcretsiz
PatroniKubernetes-native HA, etcd/consul ileÜcretsiz

Production ortamlar için pgBackRest + Patroni kombinasyonunu öneriyoruz.


Yedekleme Sağlık Kontrol Listesi

Yedek altyapınızı kurarken şu soruların yanıtı "evet" olmalı:

  • Her gece base backup alınıyor mu?
  • WAL arşivleme aktif ve boşluk yok mu? (archive_status kontrol et)
  • Yedekler farklı bir lokasyonda (off-site) mı?
  • Aylık restore testi yapılıyor mu?
  • Standby replikasyon gecikmesi izleniyor mu?
  • Failover prosedürü test edildi mi?

PostgreSQL yedekleme altyapısı kurulumu, mevcut yapının PITR'a geçişi veya replikasyon sorunlarınız için teknik görüşme talep edebilirsiniz.