Arşivleme İşlemlerinde Ağ Dosya Sistemlerini Yönetme: NFS ve SMB Üzerindeki Dizinleri Güvenli Yedekleme

Yıllar içinde onlarca farklı ortamda yedekleme scriptleri yazdım, bozulan yedekleri onardım, “neden bu dizin boş?” diye gece mesaisi yaptım. NFS veya SMB üzerindeki dizinleri arşivlemek, yerel disk arşivlemesinden çok daha fazla tuzak barındırıyor. Mount noktası boşken tar çalışıyor, ağ kesildiğinde yarım arşiv oluşuyor, izin sorunları sessizce hataları yutup yeşil dönüyor. Bu yazıda bu tuzakları bizzat deneyimlemiş biri olarak, ne yapılması gerektiğini pratik örneklerle anlatacağım.

Neden Ağ Dosya Sistemleri Farklı Davranır?

Yerel bir dizini arşivlediğinizde kernel tampon belleği, dosya sistemi tutarlılığı ve hata yönetimi nispeten öngörülebilir davranır. Ama bir NFS veya SMB mount noktası üzerinde çalışırken işin içine ağ gecikmesi, kimlik doğrulama katmanları, kilitlenme mekanizmaları ve “stale file handle” hataları giriyor.

Şu senaryoyu düşünün: Her gece çalışan bir yedekleme scripti var, /mnt/nas/data üzerinden arşiv alıyor. Mount noktası bir gece ağ sorunuyla unmount oldu. Script çalışmaya devam etti, /mnt/nas/data dizini boş göründü çünkü mount noktası artık yerel boş dizindi. tar güzelce sıfır byte’lık bir arşiv oluşturdu, iş başarılı görüntüsü verdi. Sabah açıp baktığınızda her şey yeşil ama arşiv bomboş. Bunun önüne geçmek için mount durumu kontrolünü arşivleme işleminden önce zorunlu hale getirmek gerekiyor.

Ortamı Hazırlamak: Mount Kontrolleri

Her arşivleme işleminden önce mount durumunu doğrulamak şart. Basit bir kontrol bile büyük felaketleri önler.

#!/bin/bash
# Mount durumu kontrolü
NFS_MOUNT="/mnt/nfs/data"
SMB_MOUNT="/mnt/smb/backup"

check_mount() {
    local mount_point="$1"
    if ! mountpoint -q "$mount_point"; then
        echo "HATA: $mount_point mount edilmemiş!" >&2
        exit 1
    fi
    # Dizine gerçekten erişilebildiğini doğrula
    if ! ls "$mount_point" > /dev/null 2>&1; then
        echo "HATA: $mount_point erişilemiyor (stale mount olabilir)!" >&2
        exit 1
    fi
}

check_mount "$NFS_MOUNT"
check_mount "$SMB_MOUNT"
echo "Mount kontrolleri başarılı, arşivleme başlıyor..."

mountpoint -q komutu sessizce çalışır ve çıkış kodu döner. ls ile ikinci kontrol ise “ghost mount” durumunu yakalar; yani mount tablosunda görünüp aslında erişilemeyen durumları tespit eder. Bu ikili kontrol, onlarca üretim sunucusunda işe yarayan en sağlam yaklaşım.

NFS için /etc/fstab Yapılandırması

Arşivleme scriptlerinizden önce NFS mount seçeneklerinizin doğru yapılandırıldığından emin olun. /etc/fstab içindeki mount seçenekleri kritik:

# /etc/fstab - NFS mount örneği
192.168.1.100:/export/data  /mnt/nfs/data  nfs  
  rw,sync,hard,intr,timeo=14,retrans=3,_netdev  0  0

# SMB/CIFS mount örneği
//192.168.1.200/share  /mnt/smb/backup  cifs  
  credentials=/etc/samba/backup.creds,uid=backup,
  gid=backup,file_mode=0660,dir_mode=0770,_netdev  0  0
  • hard: Sunucu yanıt vermediğinde sonsuz retry yapar, ağ kesildiğinde işlemlerin askıda kalması tercih edilir çünkü arşiv yarım kalmaz
  • intr: Kullanıcının Ctrl+C ile yarıda kesebilmesini sağlar
  • timeo=14: 1.4 saniye timeout (değer 0.1 saniye cinsinden)
  • retrans=3: 3 deneme sonrası hata döner
  • _netdev: Ağ servisleri başlamadan önce bu mount’u deneme, boot sırasında sistemi kilitlemez

tar ile NFS/SMB Arşivleme

tar komutu ağ dosya sistemleri üzerinde çalışırken dikkat edilmesi gereken birkaç önemli parametre var.

# Temel NFS arşivleme - hata kontrolüyle
tar 
  --create 
  --gzip 
  --file=/backup/nfs_data_$(date +%Y%m%d).tar.gz 
  --directory=/mnt/nfs/data 
  --one-file-system 
  --warning=no-file-changed 
  --exclude-tag-all=.nobackup 
  . 2>/var/log/backup/tar_errors_$(date +%Y%m%d).log

TAR_EXIT=$?
if [ $TAR_EXIT -eq 1 ]; then
    echo "UYARI: Bazı dosyalar arşivlenirken değişti (exit code 1)" >&2
elif [ $TAR_EXIT -gt 1 ]; then
    echo "KRİTİK HATA: tar başarısız oldu (exit code $TAR_EXIT)" >&2
    exit 1
fi
  • –one-file-system: Başka mount noktalarına taşmayı engeller, NFS içinde NFS bağlıysa onu es geçer
  • –warning=no-file-changed: Arşivleme sırasında değişen dosyalar için uyarı bastırır ama hata olarak işaretlemez
  • –exclude-tag-all=.nobackup: İçinde .nobackup dosyası olan dizinleri atlar, seçici backup için kullanışlı

tar’ın çıkış kodları bu işte çok önemli. Exit code 0 tam başarı, exit code 1 bazı dosyalarda değişiklik (genellikle kabul edilebilir), exit code 2 kritik hata anlamına gelir. Bunu her zaman kontrol edin.

Büyük Dosya Sistemleri için Incremental Arşivleme

Birkaç terabaytlık NFS share’ini her gece tam arşivleyemezsiniz. Bu noktada tar’ın incremental backup özelliği devreye girer:

#!/bin/bash
BACKUP_DIR="/backup/incremental"
SOURCE="/mnt/nfs/largeshare"
SNAPSHOT_FILE="/var/lib/backup/nfs_snapshot.snar"
DATE=$(date +%Y%m%d_%H%M)

# Haftanın başında (Pazartesi) tam yedek al
if [ "$(date +%u)" -eq 1 ]; then
    echo "Pazartesi: Tam yedek alınıyor..."
    rm -f "$SNAPSHOT_FILE"
    tar 
      --create 
      --gzip 
      --listed-incremental="$SNAPSHOT_FILE" 
      --file="${BACKUP_DIR}/full_${DATE}.tar.gz" 
      --one-file-system 
      "$SOURCE"
else
    echo "Artımlı yedek alınıyor..."
    tar 
      --create 
      --gzip 
      --listed-incremental="$SNAPSHOT_FILE" 
      --file="${BACKUP_DIR}/incremental_${DATE}.tar.gz" 
      --one-file-system 
      "$SOURCE"
fi

.snar dosyası tar’ın durumu kaydettiği snapshot dosyasıdır. Bu dosya kaybolursa incremental zinciri bozulur, dikkatli olun. Bu dosyayı da ayrı bir yerde yedeklemek iyi bir pratik.

rsync ile Ağ Üzerinde Güvenli Arşiv Transferi

Sadece tar kullanmak yeterli değil çoğu durumda. rsync ile arşivleri başka bir konuma transfer ederken ağ dosya sisteminin özelliklerini göz önünde bulundurmak gerekiyor.

# NFS share'inden yerel diske güvenli rsync
rsync 
  --archive 
  --verbose 
  --compress 
  --checksum 
  --partial 
  --progress 
  --timeout=300 
  --log-file=/var/log/backup/rsync_$(date +%Y%m%d).log 
  --exclude="*.tmp" 
  --exclude=".~lock*" 
  --exclude="~$*" 
  /mnt/nfs/data/ 
  /backup/mirror/nfs_data/
  • –checksum: Dosya değişikliğini boyut/zaman yerine checksum ile belirler, daha güvenilir ama yavaş
  • –partial: Yarıda kesilen transferi başa almaz, kaldığı yerden devam eder
  • –timeout=300: 300 saniye işlem gelmezse bağlantıyı kes, takılı kalan transferleri önler
  • –exclude=”.~lock ve –exclude=”~$: LibreOffice ve Microsoft Office kilit dosyalarını atlar, bunlar rsync hatalarına yol açar

SMB share’lerinde rsync kullanıyorsanız özellikle Windows dosyalarındaki özel karakterlere dikkat edin. --iconv parametresi karakter seti dönüşümü için kullanılabilir:

# Windows SMB share'inden Linux'a, karakter seti dönüşümüyle
rsync 
  --archive 
  --iconv=UTF-8,UTF-8 
  --exclude="desktop.ini" 
  --exclude="Thumbs.db" 
  --exclude="*.lnk" 
  /mnt/smb/windowsshare/ 
  /backup/windows_data/

İzin Sorunlarını Yönetmek

NFS ve SMB’nin en sinir bozucu tarafı izin yönetimi. NFS’de UID/GID eşleştirmesi, SMB’de ise Windows ACL’leri ciddi sorunlara yol açabilir.

NFS UID/GID Sorunları

# Hangi UID ile dosyalara erişildiğini kontrol et
stat /mnt/nfs/data/kritik_dosya.txt

# Root squashing durumunu test et (NFS sunucusunda root_squash varsa)
# root olarak touch denemesi
sudo touch /mnt/nfs/data/test_root_access 2>&1 || 
  echo "root_squash aktif, alternatif kullanıcı gerekli"

# backup kullanıcısıyla arşivleme yap
sudo -u backup tar 
  --create 
  --gzip 
  --file=/backup/nfs_$(date +%Y%m%d).tar.gz 
  --preserve-permissions 
  /mnt/nfs/data/

NFS sunucusunda root_squash aktifse, root yetkisiyle çalışan backup scriptleriniz dosyalara erişemez. Sunucu tarafında no_root_squash açmak yerine, yetkili bir backup kullanıcısı oluşturmak çok daha sağlıklı bir yaklaşım.

ACL’leri Koruyarak Arşivleme

Linux üzerinde SMB share’leri arşivlerken POSIX ACL’lerini de korumak isteyebilirsiniz:

# ACL bilgisiyle birlikte arşivleme
tar 
  --create 
  --gzip 
  --acls 
  --xattrs 
  --xattrs-include="system.posix_acl_access" 
  --xattrs-include="system.posix_acl_default" 
  --file=/backup/smb_with_acls_$(date +%Y%m%d).tar.gz 
  /mnt/smb/data/

# Arşivden geri yüklerken
tar 
  --extract 
  --gzip 
  --acls 
  --xattrs 
  --file=/backup/smb_with_acls_20241201.tar.gz 
  --directory=/restore/target/

Gerçek Dünya Senaryosu: Üretim Ortamı Yedekleme Scripti

Şimdiye kadar anlattıklarımı bir araya getiren, üretim ortamında kullanılabilir bir script. Bu script bir e-ticaret şirketinin NAS üzerindeki medya dosyaları için yazılmıştı, aylar boyunca sorunsuz çalıştı:

#!/bin/bash
# nfs_backup.sh - Üretim NFS Yedekleme Scripti
# Versiyon: 2.1

set -euo pipefail

# Yapılandırma
NFS_MOUNT="/mnt/nfs/media"
SMB_MOUNT="/mnt/smb/documents"
BACKUP_BASE="/backup/nas"
LOG_DIR="/var/log/backup"
RETENTION_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)
LOCK_FILE="/var/run/nas_backup.lock"

# Log fonksiyonu
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "${LOG_DIR}/backup_${DATE}.log"
}

# Temizlik fonksiyonu
cleanup() {
    rm -f "$LOCK_FILE"
    log "Script sonlandı (cleanup çalıştı)"
}
trap cleanup EXIT

# Çakışma kontrolü
if [ -f "$LOCK_FILE" ]; then
    PID=$(cat "$LOCK_FILE")
    if kill -0 "$PID" 2>/dev/null; then
        log "HATA: Backup zaten çalışıyor (PID: $PID)"
        exit 1
    else
        log "Eski lock dosyası temizleniyor..."
        rm -f "$LOCK_FILE"
    fi
fi
echo $$ > "$LOCK_FILE"

# Mount kontrolleri
for mount_point in "$NFS_MOUNT" "$SMB_MOUNT"; do
    if ! mountpoint -q "$mount_point"; then
        log "HATA: $mount_point mount edilmemiş, remount deneniyor..."
        mount "$mount_point" || {
            log "KRİTİK: $mount_point mount edilemedi, backup iptal!"
            exit 1
        }
    fi
    
    # Erişilebilirlik testi
    if ! timeout 10 ls "$mount_point" > /dev/null 2>&1; then
        log "HATA: $mount_point erişilemiyor (timeout veya stale handle)"
        exit 1
    fi
done

log "Mount kontrolleri başarılı"

# NFS arşivleme
log "NFS medya arşivleme başlıyor..."
mkdir -p "${BACKUP_BASE}/nfs"

tar 
  --create 
  --gzip 
  --file="${BACKUP_BASE}/nfs/media_${DATE}.tar.gz" 
  --directory="$NFS_MOUNT" 
  --one-file-system 
  --warning=no-file-changed 
  --exclude="*.tmp" 
  --exclude=".cache" 
  . 2>>"${LOG_DIR}/backup_${DATE}.log"

TAR_EXIT=$?
[ $TAR_EXIT -le 1 ] || { log "KRİTİK: NFS tar başarısız (exit: $TAR_EXIT)"; exit 1; }
log "NFS arşivi tamamlandı"

# Arşiv bütünlük kontrolü
log "Arşiv bütünlük kontrolü yapılıyor..."
if ! gzip -t "${BACKUP_BASE}/nfs/media_${DATE}.tar.gz"; then
    log "HATA: Arşiv bozuk! ${BACKUP_BASE}/nfs/media_${DATE}.tar.gz"
    exit 1
fi
log "Arşiv bütünlüğü doğrulandı"

# Eski arşivleri temizle
log "Eski arşivler temizleniyor (${RETENTION_DAYS} günden eski)..."
find "${BACKUP_BASE}" 
  -name "*.tar.gz" 
  -mtime "+${RETENTION_DAYS}" 
  -delete 
  -print >> "${LOG_DIR}/backup_${DATE}.log"

log "Yedekleme başarıyla tamamlandı"

Bu scriptte dikkat çeken nokta set -euo pipefail satırı. Herhangi bir komut hata verdiğinde script durur (-e), tanımsız değişken kullanımı hata verir (-u), pipe’larda herhangi bir komutun hata kodu iletilir (-o pipefail). Ağ dosya sistemleriyle çalışırken bu ayarlar hayat kurtarır.

Bütünlük Doğrulama ve Monitoring

Arşivi almak yetmez, alınan arşivin sağlıklı olduğunu da doğrulamak gerekir.

#!/bin/bash
# Arşiv doğrulama ve raporlama

BACKUP_DIR="/backup/nas"
REPORT_FILE="/var/log/backup/integrity_report_$(date +%Y%m%d).txt"

echo "Arşiv Bütünlük Raporu - $(date)" > "$REPORT_FILE"
echo "========================================" >> "$REPORT_FILE"

# Son 24 saatte oluşturulan arşivleri kontrol et
find "$BACKUP_DIR" -name "*.tar.gz" -mtime -1 | while read -r archive; do
    SIZE=$(du -sh "$archive" | cut -f1)
    
    if gzip -t "$archive" 2>/dev/null; then
        # İçerik listesi - ilk 5 dosya
        FILE_COUNT=$(tar -tzf "$archive" 2>/dev/null | wc -l)
        echo "OK | $archive | Boyut: $SIZE | Dosya sayısı: $FILE_COUNT" >> "$REPORT_FILE"
    else
        echo "BOZUK | $archive | Boyut: $SIZE" >> "$REPORT_FILE"
        # Alarm gönder
        echo "BOZUK ARŞİV: $archive" | mail -s "Backup Alarm" [email protected]
    fi
done

cat "$REPORT_FILE"

Monitoring tarafında da Zabbix veya Prometheus kullanıyorsanız backup script’inizin çıkış kodunu ve arşiv boyutunu bir metrik olarak göndermeyi ihmal etmeyin. “Yedek alındı” yeşili her şeyin yolunda olduğu anlamına gelmez; boyutu da takip edin. Bir gün aniden küçülen arşiv boyutu sizi uyarmalı.

Yaygın Hatalar ve Çözümleri

Sahada en çok karşılaştığım sorunları ve çözümlerini bir liste halinde paylaşayım:

  • Stale NFS Handle: umount -l /mnt/nfs/data && mount /mnt/nfs/data ile lazy unmount yapıp yeniden mount edin. Kernel NFS istemcisini bu şekilde sıfırlamak çoğu durumda işe yarar.
  • SMB Bağlantısı Düşüyor: //server/share bağlantısı uzun süre pasif kalınca düşüyorsa, /etc/samba/smb.conf veya mount seçeneklerine socket options = TCP_NODELAY IPTOS_LOWLATENCY ekleyin.
  • tar “Cannot stat” Hataları: NFS üzerinde sembolik linkler veya özel dosyalar varsa --dereference ile gerçek dosyayı arşivleyin ya da --exclude ile bu dosyaları atlayın.
  • İzin Hatası ile Boş Arşiv: Script root olarak çalışıyor ama NFS root_squash aktif. nobody kullanıcısına düşen izinler arşivi boş bırakır. Çözüm: Backup için ayrı bir kullanıcı ve NFS map_static yapılandırması kullanın.
  • Disk Dolu Hatası Arşiv Ortasında: df -h ile hedef diskte yeterli alan olduğunu önceden kontrol edin. du -sh /mnt/nfs/data ile kaynak boyutunu öğrenin, her zaman yüzde 20 fazla alanın olduğundan emin olun.
  • Encoding Sorunları (SMB): Windows tarafında Türkçe karakter içeren dosya adları Linux’ta bozuk görünüyorsa iocharset=utf8 mount seçeneğini ekleyin.

Sonuç

NFS ve SMB üzerindeki arşivleme işlemleri, yerel disk işlemlerine göre çok daha fazla özen gerektiriyor. Bu yazıda anlattığım pratikleri özetlersek:

Önce mount durumunu doğrulayın, sonra arşivleyin. Lock dosyasıyla paralel çalışmayı önleyin. set -euo pipefail ile script güvenliğini artırın. tar’ın exit code’larını mutlaka kontrol edin; 0 ve 1 kabul edilebilir, 2 kritik hata. Arşiv aldıktan sonra gzip -t ile bütünlük doğrulaması yapın. İzin sorunları için ayrı backup kullanıcısı kullanın. Monitoring’e boyut metriğini de ekleyin.

Bu alanda “bir kere kurdum, çalışıyor” yaklaşımı işe yaramıyor. Ağ altyapısı değişiyor, sunucular güncelleniyor, share izinleri değiştiriliyor. Backup scriptlerinizi düzenli aralıklarla test edin ve en önemlisi geri yükleme testleri yapın. Alınan ama geri yüklenemeyen bir arşivin hiçbir değeri yok.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir