Arşiv Oluştururken İlerlemeyi Kaydetme ve Kesilen Yedekleri Kaldığı Yerden Sürdürme
Büyük bir yedekleme işlemi başlatıyorsunuz, saat gece yarısını geçiyor, sunucu odası kliması uğulduyor ve tam 80 GB’lık arşiv oluşturma işleminin sonuna geldinken ağ bağlantısı kopuyor ya da birisi yanlışlıkla terminali kapatıyor. Sabah geldiğinizde önünüzde yarım kalmış bir tar dosyası ve “tekrar başlamalı mıyım?” sorusu var. Bu senaryoyu yaşamamış sysadmin azdır. Bu yazıda hem ilerlemeyi izlemenin hem de kesilen işlemleri kurtarmanın pratik yollarını ele alacağız.
Neden İlerleme Takibi Bu Kadar Önemli?
tar komutunun en can sıkıcı özelliklerinden biri sessizliğidir. Komutu çalıştırırsınız, cursor yanıp söner durur, hiçbir şey olmuyormuş gibi görünür. 10 GB mı işledi, 50 GB mı? Ne zaman bitecek? Hiçbir fikriniz yoktur. Özellikle production ortamlarda, bir bakım penceresi içinde çalışırken bu belirsizlik ciddi stres yaratır.
İlerleme takibi aynı zamanda şunu da sağlar: bir şeyler ters gittiğinde tam olarak nerede ters gittiğini anlayabilirsiniz. Log olmadan, ilerleme bilgisi olmadan troubleshooting adeta kör uçuşa döner.
pv ile Gerçek Zamanlı İlerleme İzleme
pv (pipe viewer) aracı, veri akışlarını izlemek için tasarlanmış mütevazı ama son derece güçlü bir araçtır. Çoğu dağıtımda varsayılan olarak gelmez ama kurulumu bir satır meselesidir.
# Debian/Ubuntu
sudo apt install pv
# RHEL/CentOS/Rocky
sudo yum install pv
# Arch
sudo pacman -S pv
Temel kullanım şu şekildedir. pv pipe içine girdiğinde akan veriyi ölçer ve ekrana bilgi basar:
tar cf - /var/www/html | pv | gzip > /backup/web_backup.tar.gz
Bu komut çalışırken şuna benzer bir çıktı görürsünüz:
2.34GiB 0:01:23 [28.7MiB/s] [ <=> ]
Ancak bu çıktı, toplam boyutu bilmediği için tamamlanma yüzdesini gösteremez. Bunu çözmek için kaynak boyutunu önceden hesaplayıp pv‘ye vermeniz gerekir:
# Önce boyutu öğren
SIZE=$(du -sb /var/www/html | awk '{print $1}')
# Sonra pv'ye bildir
tar cf - /var/www/html | pv -s $SIZE | gzip > /backup/web_backup.tar.gz
Artık çıktı şuna benzer:
2.34GiB 0:01:23 [28.7MiB/s] [===========> ] 47% ETA 0:01:32
Yüzde, hız ve tahmini bitiş süresi. Tam ihtiyacınız olan bilgiler.
pv ile Daha Ayrıntılı Çıktı
pv‘nin birkaç faydalı parametresi var:
- -s BOYUT: Toplam boyutu belirtir, yüzde ve ETA hesabı için gerekli
- -l: Byte yerine satır sayısına göre ölçer
- -n: Yüzdeyi stderr’a numerik olarak yazar, script içinde kullanışlı
- -i SANIYE: Güncelleme aralığını ayarlar, varsayılan 1 saniye
- -b: Sadece toplam byte sayısını gösterir
- -t: Geçen süreyi gösterir
- -r: Transfer hızını gösterir
Bir script içinde pv‘yi kullanıp çıktıyı log dosyasına yazmak istiyorsanız:
#!/bin/bash
BACKUP_SRC="/var/lib/mysql"
BACKUP_DST="/backup/mysql_$(date +%Y%m%d_%H%M%S).tar.gz"
LOG_FILE="/var/log/backup_progress.log"
SIZE=$(du -sb "$BACKUP_SRC" | awk '{print $1}')
echo "Yedekleme başladı: $(date)" | tee -a "$LOG_FILE"
tar cf - "$BACKUP_SRC" |
pv -s "$SIZE" -n 2>> "$LOG_FILE" |
gzip > "$BACKUP_DST"
echo "Yedekleme tamamlandı: $(date)" | tee -a "$LOG_FILE"
-n parametresi sayesinde her saniye güncellenen yüzde değeri log dosyasına yazılır. Sabah gelip log’u incelediğinizde işlemin nasıl ilerlediğini dakika dakika görebilirsiniz.
tar‘ın Kendi Verbose Modu ve İlerleme Kaydetme
tar komutuna -v verdiğinizde işlenen her dosyayı listeler, bu bazen çok fazla çıktı üretir ama bir log dosyasına yönlendirildiğinde son derece kıymetlidir. Özellikle hangi dosyada takıldığını bulmak için.
tar czf /backup/full_backup.tar.gz /data --verbose 2>&1 |
tee /var/log/backup_$(date +%Y%m%d).log
Bu yöntemle hem arşiv oluşturulur hem de işlenen tüm dosyaların listesi log dosyasında saklanır. Bir sorun çıktığında log’un sonuna bakarak son işlenen dosyayı bulabilirsiniz.
Bir adım daha ileri götürelim. tar‘ın --checkpoint özelliği belirli aralıklarla bir işaret basar:
tar czf /backup/full_backup.tar.gz /data
--checkpoint=1000
--checkpoint-action=echo="%T"
Her 1000 blokta bir işlenen dosya adını ekrana basar. Bunu özelleştirebilirsiniz:
tar czf /backup/full_backup.tar.gz /data
--checkpoint=500
--checkpoint-action=ttyout="İşleniyor: %Tn"
Kesilen Yedeklemeyi Kaldığı Yerden Sürdürme: Gerçekçi Bir Değerlendirme
Şunu açıkça söylemek gerekiyor: standart tar ile gerçek anlamda “kaldığı yerden devam” mümkün değildir. tar bir arşiv formatıdır ve yarım kalmış bir tar dosyası teknik olarak bozuktur. Ancak birkaç farklı yaklaşımla bu sorunu çözebilirsiniz.
Yaklaşım 1: --listed-incremental ile Artımlı Yedekleme
Bu en temiz ve production’a uygun çözümdür. tar‘ın artımlı yedekleme özelliği, bir “snapshot” dosyası tutar ve sadece yeni/değişen dosyaları arşive ekler. Kesilen işlem için değil ama büyük yedekleme stratejisi için son derece değerlidir.
# İlk tam yedek
tar czf /backup/full_backup_$(date +%Y%m%d).tar.gz
--listed-incremental=/backup/snapshot.snar
/data
# Sonraki gün değişen dosyalar
tar czf /backup/incremental_$(date +%Y%m%d).tar.gz
--listed-incremental=/backup/snapshot.snar
/data
.snar dosyası her dosyanın son değiştirilme zamanını ve inode bilgisini içerir. Kesilen tam yedek sonrası artımlı çalışmayla en azından yeni/değişen dosyaları kurtarabilirsiniz.
Yaklaşım 2: --exclude-from ile İşlenen Dosyaları Atlama
Eğer -v ile verbose çalıştırdıysanız ve log dosyanız varsa, işlenen dosyaları bir listeye çevirip yeni arşivden hariç tutabilirsiniz:
# Mevcut log'dan işlenmiş dosya listesini çıkar
grep "^data/" /var/log/backup_20240115.log > /tmp/already_done.txt
# Kalan dosyaları ayrı bir arşivde yedekle
tar czf /backup/remaining_backup.tar.gz
--exclude-from=/tmp/already_done.txt
/data
Bu yaklaşım mükemmel değildir, çünkü log’da son satırlardaki dosyalar yarım işlenmiş olabilir. Güvenli tarafta kalmak için log’un son 100 satırındaki dosyaları da hariç bırakmak mantıklıdır:
# Son 100 satırı çıkar, bunlar riskli
tail -100 /var/log/backup_20240115.log > /tmp/risky_files.txt
# Güvenli listeyi oluştur
head -n -100 /var/log/backup_20240115.log > /tmp/safe_done.txt
Yaklaşım 3: rsync + tar Kombinasyonu
Büyük yedekleme işleri için benim tercih ettiğim yöntem şudur: önce rsync ile veriyi lokal bir staging alanına çekin, sonra tar ile arşivleyin. Rsync --partial ve --progress parametreleriyle kesilen transferleri sürdürebilir.
# Önce rsync ile staging'e al, kesintiye dayanıklı
rsync -av --partial --progress
/var/www/html/
/staging/html_snapshot/
# Sonra tar ile arşivle, çok daha hızlı çünkü lokal
tar czf /backup/html_$(date +%Y%m%d).tar.gz
-C /staging html_snapshot/
rsync --partial yarım kalan dosyaları geçici dosya olarak saklar ve bağlantı yeniden kurulduğunda kaldığı yerden devam eder. Bu özellikle ağ üzerinden yedekleme alırken hayat kurtarır.
screen veya tmux ile Oturum Kesintisine Karşı Koruma
Yedekleme işleminin kesilmesinin en yaygın nedeni SSH oturumunun kapanmasıdır. Bunu önlemenin en pratik yolu screen ya da tmux kullanmaktır.
# Yeni bir tmux oturumu başlat
tmux new-session -s backup
# Yedekleme komutunu çalıştır
tar czf /backup/big_backup.tar.gz /data | pv -s $(du -sb /data | awk '{print $1}')
# Detach et (Ctrl+B sonra D)
# SSH bağlantısını kes, sunucu çalışmaya devam eder
# Geri döndüğünde oturuma bağlan
tmux attach-session -t backup
Bu basit önlem sayesinde “terminal kapandı, yedek gitti” sorununu tamamen ortadan kaldırırsınız. Her büyük yedekleme işlemini tmux veya screen altında başlatmak artık bir refleks haline gelmeli.
Benzer şekilde nohup da kullanılabilir:
nohup tar czf /backup/big_backup.tar.gz /data
--checkpoint=1000
--checkpoint-action=echo="%T"
> /var/log/backup_$(date +%Y%m%d).log 2>&1 &
echo "PID: $!"
nohup ile başlatılan işlem terminali kapatıldıktan sonra da çalışmaya devam eder. PID’i kaydedin, sonradan tail -f ile log’u izleyebilirsiniz.
Gzip Yerine pigz ile Paralel Sıkıştırma ve İzleme
Büyük arşivlerde gzip tek çekirdek kullandığı için darboğaz yaratır. pigz (parallel gzip) çok çekirdekli sıkıştırma sağlar ve pv ile güzel entegre olur:
# pigz kurulumu
sudo apt install pigz # veya yum install pigz
# Paralel sıkıştırma ile yedekleme ve ilerleme izleme
SIZE=$(du -sb /data | awk '{print $1}')
tar cf - /data |
pv -s "$SIZE" -p -r -e |
pigz -p 4 > /backup/data_$(date +%Y%m%d).tar.gz
-p 4 parametresi 4 CPU çekirdeği kullanır. 8 çekirdekli bir sunucuda bu işlemi neredeyse 3-4 kat hızlandırabilir.
Pratik Bir Monitoring Script’i
Tüm bu bilgileri bir araya getiren, production’da kullanılabilir bir script yazalım:
#!/bin/bash
# backup_with_progress.sh
# Kullanim: ./backup_with_progress.sh /kaynak /hedef/backup_adi.tar.gz
set -euo pipefail
SOURCE="${1:?Kaynak dizin belirtinmedi}"
DESTINATION="${2:?Hedef dosya belirtilmedi}"
LOG_DIR="/var/log/backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOG_FILE="${LOG_DIR}/backup_${TIMESTAMP}.log"
PID_FILE="/var/run/backup_${TIMESTAMP}.pid"
mkdir -p "$LOG_DIR"
# pv kurulu mu kontrol et
if ! command -v pv &> /dev/null; then
echo "HATA: pv kurulu degil. 'apt install pv' veya 'yum install pv' ile kurun."
exit 1
fi
# Kaynak boyutunu hesapla
echo "[$(date '+%H:%M:%S')] Kaynak boyutu hesaplaniyor..." | tee -a "$LOG_FILE"
TOTAL_SIZE=$(du -sb "$SOURCE" | awk '{print $1}')
HUMAN_SIZE=$(du -sh "$SOURCE" | awk '{print $1}')
echo "[$(date '+%H:%M:%S')] Toplam boyut: $HUMAN_SIZE ($TOTAL_SIZE byte)" | tee -a "$LOG_FILE"
# PID dosyasini olustur
echo $$ > "$PID_FILE"
# Temizlik fonksiyonu
cleanup() {
rm -f "$PID_FILE"
if [ $? -ne 0 ]; then
echo "[$(date '+%H:%M:%S')] HATA: Yedekleme basarisiz!" | tee -a "$LOG_FILE"
fi
}
trap cleanup EXIT
echo "[$(date '+%H:%M:%S')] Yedekleme basliyor..." | tee -a "$LOG_FILE"
echo "[$(date '+%H:%M:%S')] Kaynak: $SOURCE" | tee -a "$LOG_FILE"
echo "[$(date '+%H:%M:%S')] Hedef: $DESTINATION" | tee -a "$LOG_FILE"
# Ana yedekleme komutu
tar cf - "$SOURCE"
--checkpoint=1000
--checkpoint-action=echo="[$(date '+%H:%M:%S')] Checkpoint: %T" 2>> "$LOG_FILE" |
pv -s "$TOTAL_SIZE" -p -r -e -t |
gzip > "$DESTINATION"
BACKUP_SIZE=$(du -sh "$DESTINATION" | awk '{print $1}')
echo "[$(date '+%H:%M:%S')] Tamamlandi. Arşiv boyutu: $BACKUP_SIZE" | tee -a "$LOG_FILE"
echo "[$(date '+%H:%M:%S')] Log dosyasi: $LOG_FILE"
Bu scripti çalıştırdığınızda hem ekranda gerçek zamanlı ilerleme görürsünüz hem de log dosyasında tam bir kayıt tutulur.
Yarım Kalan Arşivi Doğrulama ve Kurtarma
Bazen kesilen bir işlem sonucu elde ettiğiniz bozuk tar dosyasından sağlam kısımları kurtarmanız gerekebilir. tar bu durumda bile bir miktar yardımcı olabilir:
# Arşiv içeriğini test et, hatada dur
tar tzf /backup/broken_backup.tar.gz 2>&1 | tail -20
# Erişilebilen dosyaları listele, hataları atla
tar tzf /backup/broken_backup.tar.gz 2>/dev/null | wc -l
# Kurtarılabilen dosyaları çıkar
tar xzf /backup/broken_backup.tar.gz
--ignore-zeros
-C /recovery/ 2>/dev/null || true
# Ne kadar kurtarıldığını gör
du -sh /recovery/
--ignore-zeros parametresi arşiv içindeki sıfır blokları (genellikle dosya sonu işareti) atlar ve elimine kadar veriyi okumaya devam eder. Tam bir kurtarma sağlamaz ama %90 oranında işe yarar.
Sonuç
Yedekleme işlemleri sysadmin’in en kritik sorumluluklarından biridir ve “çalışıyor gibi görünüyor” yetmez. İlerleme izleme, hem operasyonel farkındalık hem de sorun tespiti açısından vazgeçilmezdir.
Özetlemek gerekirse:
pvile her tar komutuna ilerleme bilgisi eklenebilir, kurmayanlar için iyi bir neden yok--checkpointparametresi tar’ın kendi ilerleme mekanizmasını aktive edertmuxveyascreenkullanmak SSH kopması riskini ortadan kaldırır--listed-incrementalbüyük veri setleri için artımlı yedekleme stratejisi sağlarrsync --partialağ üzerinden alınan yedekler için kesintiye karşı en güvenilir yöntemdir- Bozuk arşivlerden kurtarma için
--ignore-zerosilk denenmesi gereken seçenektir
Her şeyden önce şunu aklınızda tutun: en iyi kesinti yönetimi, kesintinin etkisini minimuma indiren bir mimari kurmaktır. Artımlı yedekleme, aşamalı arşivleme ve düzgün oturum yönetimi ile “kesilen yedek” problemi büyük ölçüde tarihsel bir anekdota dönüşür.
