Yedeği olmayan veri, olmayan veridir. Diskt çökmesi, ransomware, insan hatası — hepsi aynı anda gelir. Bu yazı üretim seviyesinde bir backup stratejisinin unsurlarını ve hem PostgreSQL hem MySQL''de nasıl uygulanacağını anlatır.

3-2-1 Kuralı

İlgili rehberler: Yazılım geliştirme süreçleri · PostgreSQL optimizasyonu · Git ileri seviye komutlar · Redis nedir, nasıl kullanılır · Docker ile deploy

  • 3 kopya (1 ana + 2 yedek)
  • 2 farklı ortam (disk + cloud)
  • 1 offsite (fiziksel olarak ayrı bir yerde)
Uyarı
Yedek dosyasını aynı sunucuda tutmak yedek değildir — disk çökünce yedek de gider. Ransomware bulaşırsa mount edilmiş tüm dosyalar şifrelenir.

Yedek Tipleri

  • Full backup: Tüm DB''nin tam kopyası. Haftalık önerilir
  • Incremental: Son full/incremental''dan beri değişenler. Günlük
  • Differential: Son full''dan beri değişenler (büyür)
  • WAL / binlog: Her transaction''ın logu — PITR için gerekli

PostgreSQL Yedek

Logical Backup (pg_dump)

# Tek DB
pg_dump -h localhost -U postgres -Fc -f /backup/mydb-$(date +%F).dump mydb

# -Fc = custom format (compressed, pg_restore ile esnek)
# -Fd = directory format (paralel -j için)
# -Fp = plain SQL (büyük DB için kötü)

# Paralel (büyük DB)
pg_dump -h localhost -U postgres -Fd -j 4 -f /backup/mydb-dir mydb

# Tüm cluster
pg_dumpall -h localhost -U postgres -f /backup/cluster-$(date +%F).sql

# Geri yükleme
dropdb mydb && createdb mydb
pg_restore -d mydb /backup/mydb-2026-04-17.dump

Physical Backup (pg_basebackup) + WAL → PITR

# Archive mode'u aç (postgresql.conf)
wal_level = replica
archive_mode = on
archive_command = 'cp %p /backup/wal/%f'
archive_timeout = 300

# Base backup al
pg_basebackup -h localhost -U replicator -D /backup/base -Ft -z -P

# PITR: bir saat öncesine dönüş
# 1) servisi durdur
systemctl stop postgresql
# 2) data dizinini boşalt, base backup'ı aç
tar xzf /backup/base/base.tar.gz -C /var/lib/postgresql/data
# 3) recovery.conf oluştur
cat > /var/lib/postgresql/data/recovery.signal
cat > /var/lib/postgresql/data/postgresql.auto.conf <<EOF
restore_command = 'cp /backup/wal/%f %p'
recovery_target_time = '2026-04-17 13:45:00'
EOF
# 4) başlat
systemctl start postgresql

MySQL Yedek

# mysqldump — küçük/orta DB
mysqldump -u root -p --single-transaction --triggers --routines --events \
    --all-databases | gzip > /backup/all-$(date +%F).sql.gz

# xtrabackup — büyük DB için fiziksel yedek (hot backup)
xtrabackup --backup --target-dir=/backup/base --user=root --password=x
xtrabackup --prepare --target-dir=/backup/base

# PITR için binlog aktif olmalı
# my.cnf
server-id = 1
log_bin = /var/lib/mysql/binlog
binlog_format = ROW

# Point-in-time restore:
mysqlbinlog --start-datetime='2026-04-17 12:00:00' \
            --stop-datetime='2026-04-17 13:45:00' \
            /var/lib/mysql/binlog.000042 | mysql -u root -p

Otomatik Yedek Scripti

#!/bin/bash
# /opt/scripts/pg-backup.sh
set -euo pipefail

DB="mydb"
BACKUP_DIR="/backup/postgres"
RETAIN_DAYS=14
S3_BUCKET="s3://my-backups/postgres"
TS=$(date +%F-%H%M)
FILE="${BACKUP_DIR}/${DB}-${TS}.dump"

mkdir -p "$BACKUP_DIR"

# 1) Dump
pg_dump -Fc -f "$FILE" "$DB"

# 2) Checksum
sha256sum "$FILE" > "${FILE}.sha256"

# 3) S3'e yükle (offsite)
aws s3 cp "$FILE" "$S3_BUCKET/"
aws s3 cp "${FILE}.sha256" "$S3_BUCKET/"

# 4) Eski yerel dosyaları temizle
find "$BACKUP_DIR" -name "${DB}-*.dump" -mtime +$RETAIN_DAYS -delete

# 5) Webhook/Slack bildir
curl -sS -X POST https://hooks.slack.com/... \
    -d "{\"text\":\"Backup done: $FILE ($(du -h $FILE | cut -f1))\"}"
# Cron
0 2 * * * /opt/scripts/pg-backup.sh >> /var/log/pg-backup.log 2>&1

Restore Testi

Test edilmemiş yedek, yedek değildir. En az ayda bir farklı bir sunucuda yedeği geri yükleyin ve çalıştığını doğrulayın. Felaket anında fark ettiğiniz dump bozukluğu firma bitirir.

İpucu
Restore süresi (RTO) — 500 GB''lık DB''niz dump''tan 4 saatte dönüyorsa buna tolerans gösterebiliyor musunuz? Hayırsa physical backup + streaming replica tercih edin.

Şifreleme ve Retention

  • Yedek dosyalarını AES-256 ile şifrele (gpg --symmetric --cipher-algo AES256)
  • S3 bucket''ta SSE-KMS aktif
  • Retention policy: günlük 14 gün, haftalık 12 hafta, aylık 12 ay
  • GDPR/KVKK: kişisel veri içeren yedekler için retention süresi yasal zorunluluk

Monitoring

# Son yedek tarihi nagios/grafana metriği
LAST=$(ls -t /backup/postgres/*.dump | head -1 | xargs stat -c %Y)
AGE=$(( ($(date +%s) - $LAST) / 3600 ))
echo "pg_backup_age_hours $AGE"
# 25 saati geçtiyse alert

Modern Yazılım Geliştirme ve DevOps Pratikleri

Profesyonel yazılım geliştirme süreci üç pillar üzerine kuruludur: kaynak kontrolü (Git + GitHub/GitLab pull request akışı, code review zorunlu), CI/CD pipeline (otomatik test + lint + build + deploy), ve gözlemlenebilirlik (Sentry/Datadog/Grafana ile log, metric, trace toplama). Test piramidi (unit > integration > e2e) ile kod kalitesini garantilemek, mikroservis mimarisinde Docker container ve Kubernetes orkestrasyonu kullanmak, REST veya GraphQL API tasarımında OpenAPI/GraphQL Schema sözleşmesi tutmak modern standardlardır. Yazılım geliştirme yaşam döngüsü boyunca (gereksinim → tasarım → implementasyon → test → deploy → bakım) Agile/Scrum sprintleri 1-2 hafta, DevOps takımları sürekli teslim (continuous delivery) prensibiyle çalışır.

Veritabanı backup stratejisi

PITR, offsite yedekleme, disaster recovery planı ve retention politikası için iletişime geçin

WhatsApp