Arşivleme Sırasında Disk Dolunca Ne Yapmalı: Yarım Kalan tar Yedeğini Temizleme ve Alanı Geri Kazanma
Gece 02:30’da telefon çalar. Monitoring sistemi alarm veriyor, yedekleme sunucusundaki disk dolmuş. Üstelik o an çalışan tar işlemi yarım kalmış, 800 GB’lık bir dosya sistemi yedeği tam ortasında kesilmiş. Sabah 08:00’de iş yerine gelen kullanıcılar sistemin yavaş çalıştığını fark etmeye başlayacak çünkü yedekleme dizini production sunucusuyla aynı disk grubunda. Bu senaryoyu yaşadıysanız, bu yazı tam size göre.
Durumu Anlamak: Panik Yapmadan Önce Neyin Nerede Olduğunu Öğren
İlk refleks genellikle yanlış: “Hemen o büyük dosyayı siliyim.” Dur bir saniye. Yarım kalan tar arşivi bazen beklenenden çok daha fazla yer kaplar ve bazen de hâlâ open file handle’larla tutulmaktadır. Silmeden önce durumu netleştirmek gerekiyor.
# Disk kullanımına genel bakış
df -h
# Hangi dizin ne kadar yer kaplıyor
du -sh /backup/* | sort -rh | head -20
# Şu anda açık olan büyük dosyalar (silindi ama yer bırakmayan dosyalar dahil)
lsof | grep deleted | awk '{print $7, $9}' | sort -rn | head -10
Bu üç komutun çıktısını bir arada değerlendirmek gerekiyor. df -h size disk doluluk oranını verir. du -sh ise gerçekten hangi dizinin suçlu olduğunu gösterir. lsof | grep deleted kısmı ise en sık atlanan ama en kritik adım: bir process dosyayı silmiş ama hâlâ üzerinde çalışıyorsa, disk alanı o process ölene kadar geri gelmez.
Yarım Kalan tar İşlemi Hâlâ Çalışıyor mu?
# Aktif tar process'lerini kontrol et
ps aux | grep tar | grep -v grep
# tar'ın hangi dosyaya yazdığını bul
lsof -p <PID> | grep -E ".tar|.tar.gz|.tgz"
# tar'ın ne kadar ilerlediğini anlık takip et
ls -lh /backup/yedek_dosya.tar.gz
watch -n 5 'ls -lh /backup/yedek_dosya.tar.gz'
Eğer tar hâlâ çalışıyorsa, önce onu durdurmanız gerekiyor. Ama nasıl durdurduğunuz önemli: SIGKILL ile öldürmek yerine SIGTERM ile nazikçe sonlandırmak, bazı durumlarda tar’ın daha düzgün kapanmasını sağlar (her ne kadar tar genellikle yarım arşivi temizlemese de).
# Önce SIGTERM ile dene
kill -SIGTERM <PID>
# 10 saniye bekle, hâlâ çalışıyorsa:
kill -9 <PID>
# Process gerçekten öldü mü?
ps -p <PID>
Yarım Kalan Arşiv Dosyasını Güvenle Silmek
Process öldükten sonra karşınızda büyük ihtimalle bozuk, yarım kalmış bir tar dosyası var. Bu dosyanın silinmesi gerekiyor ama önce ne olduğunu kayıt altına almak iyi bir alışkanlık:
# Dosya boyutunu ve tarihini kaydet (sonradan raporlama için)
ls -lh /backup/yedek_dosya.tar.gz >> /var/log/backup_incident.log
echo "$(date): Yarım kalan arşiv silindi, disk doluluk nedeniyle" >> /var/log/backup_incident.log
# Dosyayı sil
rm -f /backup/yedek_dosya.tar.gz
# Silme işlemi sonrası alanı kontrol et
df -h
Bazen rm komutundan sonra df -h hâlâ aynı değeri gösteriyorsa paniklemeyın. Kernel bazen bu değeri birkaç saniye gecikmeyle günceller. 10-15 saniye bekleyip tekrar kontrol edin. Değer hâlâ değişmediyse lsof | grep deleted ile silinmiş ama tutulmuş dosya var mı diye tekrar bakın.
Silindi Ama Alan Geri Gelmedi: Deleted Files Tuzağı
Bu durum özellikle log rotate veya yedekleme scriptlerinin yarım kaldığı senaryolarda çok sık yaşanır:
# Silindi ama hâlâ yer kaplayan dosyaları bul
lsof +L1
# Daha detaylı çıktı için
lsof +L1 | awk 'NR>1 {print $2, $7, $9}' | sort -k2 -rn
# Hangi process tuttuğunu gör
lsof +L1 | grep -v COMMAND | awk '{print "PID:", $2, "Boyut:", $7, "Dosya:", $NF}'
Çıktıda gördüğünüz PID, o dosyayı tutan process. Eğer bu process yedekleme işleminin kendisiyse ve zaten sonlandırmak istediğiniz buysa, tekrar kill edin. Eğer başka bir kritik process tutuyorsa (mesela syslog), o process’i yeniden başlatmak da sorunu çözer:
# Örneğin syslog tutuyorsa
systemctl restart rsyslog
# Kontrol et
lsof +L1
df -h
Dolu Diskte Güvenli Temizlik Stratejisi
Yalnızca o bir dosyayı silmek yetmeyebilir. Disk doluysa, büyük ihtimalle başka biriken şeyler de vardır. Sırayla kontrol etmek gerekiyor.
Eski Yedekleri Bulmak ve Temizlemek
# 7 günden eski tar dosyalarını bul
find /backup -name "*.tar.gz" -mtime +7 -ls
# Güvenli görünüyorsa sil
find /backup -name "*.tar.gz" -mtime +7 -delete
# Veya önce listele, sonra onaylayarak sil
find /backup -name "*.tar.gz" -mtime +7 -exec ls -lh {} ;
# Çıktıyı inceledikten sonra:
find /backup -name "*.tar.gz" -mtime +7 -exec rm -f {} ;
-mtime +7: 7 günden eski dosyalar anlamına gelir. -ls: Dosya detaylarını listeler, silmeden önce görmek için kullanışlıdır. -delete: Dosyaları siler, -exec rm ile eşdeğerdir ama daha hızlıdır.
Geçici ve Yarım Kalan Tüm Arşiv Dosyalarını Tespit Etmek
Sadece .tar.gz değil, tar işlemleri farklı uzantılarla geçici dosyalar bırakabilir:
# Farklı arşiv uzantılarını birlikte ara
find /backup /tmp /var/tmp -type f (
-name "*.tar"
-o -name "*.tar.gz"
-o -name "*.tgz"
-o -name "*.tar.bz2"
-o -name "*.tar.xz"
) -mtime +1 -ls 2>/dev/null
# Boyuta göre sırala (en büyükler üstte)
find /backup -type f -name "*.tar*" -printf '%s %pn' | sort -rn | head -20
Bu komutun çıktısını dikkatlice incelemenizi öneririm. Bazen 2-3 günlük “tamamlanmış gibi görünen” ama aslında bozuk arşivler de burada çıkar.
Disk Alanını Akıllıca Geri Kazanmak
Sadece silmek değil, kazanılan alanı verimli kullanmak da önemli. Disk tekrar dolmasın diye birkaç şeyi düzeltmek gerekiyor.
Yedekleme Scriptini Disk Kontrolüyle Güncellemek
Yaşanan olayın tekrar yaşanmaması için yedekleme scriptine bir önlem eklemek şart. Aşağıdaki örnek, tar başlamadan önce yeterli alan olup olmadığını kontrol eder:
#!/bin/bash
BACKUP_DIR="/backup"
SOURCE_DIR="/var/www"
TARIH=$(date +%Y%m%d_%H%M)
ARŞIV_ADI="${BACKUP_DIR}/web_yedek_${TARIH}.tar.gz"
MIN_ALAN_GB=10 # Minimum gerekli alan (GB)
# Mevcut boş alanı kontrol et (GB cinsinden)
BOS_ALAN=$(df -BG "${BACKUP_DIR}" | awk 'NR==2 {gsub("G",""); print $4}')
if [ "${BOS_ALAN}" -lt "${MIN_ALAN_GB}" ]; then
echo "HATA: Yedekleme dizininde yeterli alan yok. Mevcut: ${BOS_ALAN}GB, Gerekli: ${MIN_ALAN_GB}GB"
logger -t backup_script "Disk alanı yetersiz, yedek alınamadı. Mevcut: ${BOS_ALAN}GB"
exit 1
fi
# Eski yedekleri temizle (5 günden eskiler)
find "${BACKUP_DIR}" -name "*.tar.gz" -mtime +5 -delete
logger -t backup_script "Eski yedekler temizlendi"
# Yedek al
tar -czf "${ARŞIV_ADI}" "${SOURCE_DIR}" 2>/dev/null
if [ $? -eq 0 ]; then
logger -t backup_script "Yedek başarıyla alındı: ${ARŞIV_ADI}"
else
rm -f "${ARŞIV_ADI}"
logger -t backup_script "HATA: Yedek alınamadı, yarım dosya silindi"
exit 1
fi
Bu script basit ama etkili. logger komutu sayesinde syslog’a kayıt düşülüyor, sabah geldiğinizde journalctl -t backup_script ile ne olduğunu görebiliyorsunuz.
tar’ı Disk Doluluğuna Karşı Dayanıklı Çalıştırmak
tar’ın kendisi disk dolduğunda genellikle hata kodu döner ama sessizce ölür. --checkpoint ile biraz daha kontrol sahibi olabilirsiniz:
# Her 1000 dosyada bir ilerleme bilgisi göster
tar -czf /backup/yedek.tar.gz /data
--checkpoint=1000
--checkpoint-action=echo="%T"
# Daha iyisi: pv ile ilerlemeyi izle (pv kurulu değilse: apt install pv / yum install pv)
tar -cf - /data | pv -s $(du -sb /data | awk '{print $1}') | gzip > /backup/yedek.tar.gz
pv komutu size gerçek zamanlı hız, tamamlanma yüzdesi ve tahmini bitiş süresi gösterir. Gece başlattığınız bir yedek için inanılmaz faydalı.
Bozuk Arşivin İçini Kontrol Etmek
Bazen yarım kalan arşivi doğrudan silmek yerine, içinde ne var diye bakıp kurtarılabilecek bir şey olup olmadığını anlamak isteyebilirsiniz. Bu özellikle tam yedek alınamıyorsa ve kısmi kurtarma gerekiyorsa işe yarıyor:
# Arşiv içeriğini listele (bozuksa hata verir, ama kısmen listeler)
tar -tzf /backup/yedek_bozuk.tar.gz 2>/dev/null | head -50
# Bozuk arşivden sağlam dosyaları kurtarmaya çalış
tar -xzf /backup/yedek_bozuk.tar.gz
--ignore-zeros
--continue-file=/tmp/tar_devam
-C /tmp/kurtarilan/ 2>/dev/null
# Ne kadarı kurtarıldı?
du -sh /tmp/kurtarilan/
find /tmp/kurtarilan/ -type f | wc -l
–ignore-zeros: Boş bloklar gördüğünde durmak yerine devam eder. -C: Çıkarma hedef dizini. –continue-file: Kaldığı yerden devam etme için checkpoint dosyası.
Gerçekçi olmak gerekirse, çoğu durumda gzip ile sıkıştırılmış bir arşiv ortadan kesilmişse, sıkıştırma akışı bozulduğu için kurtarma imkânı oldukça sınırlıdır. .tar (sıkıştırmasız) arşivlerde kurtarma çok daha başarılıdır.
Arşiv Bütünlüğünü Doğrulama Alışkanlığı Edinmek
Yaşanan olayın asıl dersi şu: yedek alındıktan sonra test edilmeli. Bunu otomasyona dahil etmek, “yedek var ama açılmıyor” felaketini önler:
# Arşiv bütünlüğünü test et (açmadan)
tar -tzf /backup/yedek.tar.gz > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "Arşiv sağlam"
else
echo "HATA: Arşiv bozuk!"
# Alarm gönder, sil, yeniden al...
fi
# gzip bütünlüğü ayrıca test et
gzip -t /backup/yedek.tar.gz && echo "Gzip OK" || echo "Gzip HATA"
Bu iki kontrol birbirinden farklı şeyler test ediyor. tar -t arşiv içindeki dosya listesini okuyor, gzip -t ise sıkıştırma katmanının bütünlüğünü doğruluyor. İkisi de geçmeli.
Tekrar Yaşamamak İçin Monitoring
Disk dolmadan uyarı almak, yangın söndürmekten çok daha iyidir. Basit bir cron ile bunu halledebilirsiniz:
#!/bin/bash
# /usr/local/bin/disk_alarm.sh
# Cron: */15 * * * * /usr/local/bin/disk_alarm.sh
ESIK=85 # Yüzde doluluk eşiği
MAIL="[email protected]"
df -H | grep -vE '^Filesystem|tmpfs|cdrom|udev' | awk '{print $5 " " $1 " " $6}' | while read cikti; do
kullanim=$(echo "$cikti" | awk '{print $1}' | tr -d '%')
bolum=$(echo "$cikti" | awk '{print $2}')
mount=$(echo "$cikti" | awk '{print $3}')
if [ "${kullanim}" -gt "${ESIK}" ]; then
mesaj="UYARI: ${mount} (${bolum}) %${kullanim} dolu - $(hostname)"
echo "${mesaj}" | mail -s "Disk Alarm: $(hostname)" "${MAIL}"
logger -t disk_alarm "${mesaj}"
fi
done
15 dakikada bir çalışır, %85 eşiğini geçince mail atar. Basit, hafif, güvenilir. Fancy bir monitoring altyapısı kurmaya gerek yok.
Acil Durumda Hızlı Alan Açma Rehberi
Daha önce bahsettiklerimizi sıralı bir kontrol listesi olarak özetleyeyim. Gece 02:30’da disk dolduğunda sırayla bunları uygulayın:
- 1. Adım:
df -hile durumu gör - 2. Adım:
du -sh /backup/* | sort -rh | head -20ile suçlu dizini bul - 3. Adım:
lsof +L1ile silindi ama tutulmuş dosyaları kontrol et - 4. Adım:
ps aux | grep tarile çalışan tar var mı bak - 5. Adım: Çalışan tar varsa
kill -SIGTERMile sonlandır - 6. Adım: Yarım kalan arşivi
rm -file sil - 7. Adım:
df -hile alan geri geldi mi kontrol et - 8. Adım: Gelmedi ise
lsof +L1tekrar çalıştır, tutan process’i bul ve yeniden başlat - 9. Adım:
find /backup -name "*.tar.gz" -mtime +7 -deleteile eskileri temizle - 10. Adım: Sabah gelince yedekleme scriptine disk kontrolü ekle
Sonuç
Disk dolması ve yarım kalan arşivler, Linux ortamlarında en sık karşılaşılan ve en panik yaratan senaryolardan biri. Ama aslında sistematik yaklaşıldığında 10-15 dakikada çözülüyor. Asıl sorun genellikle teknik bilgi eksikliği değil, panikle yanlış sırayla adım atmak.
lsof +L1 komutu bu senaryoda altın değerinde. Çoğu sysadmin “sildim ama alan gelmedi” diye saatlerce uğraşırken aslında sorun tek bir komutla tespit edilebilir durumda. Bu komutu aklınızda tutun.
Uzun vadede ise asıl çözüm reaktif değil proaktif olmak: yedekleme scriptine disk kontrolü eklemek, pv ile arşiv ilerlemeyi izlemek, tamamlanan arşivleri gzip -t ile doğrulamak ve basit bir disk alarm script’iyle %85 dolulukta uyarı almak. Bu dört önlem alındıktan sonra bu tür olaylar neredeyse sıfıra iniyor.
Gece alarmı almak istemiyor musunuz? O zaman alarmı gece değil gündüz aldığınızdan emin olun.
