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
.nobackupdosyası 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/dataile 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/sharebağlantısı uzun süre pasif kalınca düşüyorsa,/etc/samba/smb.confveya mount seçeneklerinesocket options = TCP_NODELAY IPTOS_LOWLATENCYekleyin.
- tar “Cannot stat” Hataları: NFS üzerinde sembolik linkler veya özel dosyalar varsa
--dereferenceile gerçek dosyayı arşivleyin ya da--excludeile bu dosyaları atlayın.
- İzin Hatası ile Boş Arşiv: Script root olarak çalışıyor ama NFS
root_squashaktif.nobodykullanıcısına düşen izinler arşivi boş bırakır. Çözüm: Backup için ayrı bir kullanıcı ve NFSmap_staticyapılandırması kullanın.
- Disk Dolu Hatası Arşiv Ortasında:
df -hile hedef diskte yeterli alan olduğunu önceden kontrol edin.du -sh /mnt/nfs/dataile 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=utf8mount 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.
