Sunucunuzda Disk Doldu: Yer Açmak için Adım Adım Rehber

Saat gece 02:30. Telefon çalıyor. “Hocam site açılmıyor, veritabanı hata veriyor.” Monitöre bakıyorsunuz, SSH bağlanıyorsunuz, ilk komutunuz df -h. Sonuç: /dev/sda1 100% /. İşte o an. Paniği bir kenara bırakın, bu rehber tam olarak o an için yazıldı.

Disk dolması, sysadmin hayatının kaçınılmaz gerçeklerinden biri. Önemli olan paniklemeden, sistematik şekilde hareket etmek. Yanlış dosyayı silmek, production ortamını daha da berbat edebilir. Bu yüzden önce teşhis, sonra müdahale.

Durumu Anlamak: Teşhis Aşaması

Disk dolduğunda ilk refleks “bir şeyler sil” olmak zorunda değil. Önce neyin ne kadar yer kapladığını anlamak gerekiyor. Körü körüne silme işlemi kritik dosyaları kaybettirebilir.

Genel Disk Durumuna Bakış

df -h

Bu komut tüm mount noktalarını gösterir. %100 gören mount noktasını not edin. Bazen / değil, /var veya /tmp dolmuş olabilir. Bu ayrım önemli çünkü müdahale stratejinizi etkiler.

df -hi

Küçük i parametresi inode kullanımını gösterir. Disk dolmuş gibi görünüp aslında inode tükenmiş sunucular gördüm. Özellikle çok sayıda küçük dosya üreten uygulamalarda (mail server, session dosyaları) bu senaryo sıklıkla karşıma çıktı.

Hangi Dizin Ne Kadar Yer Kaplıyor

du -sh /* 2>/dev/null | sort -rh | head -20

Bu komut kök dizindeki her klasörün boyutunu büyükten küçüğe sıralar. 2>/dev/null kısmı permission hatalarını bastırır. Genellikle /var, /home veya /opt suçlu çıkar.

Şüpheli dizini bulduktan sonra içine inebilirsiniz:

du -sh /var/* 2>/dev/null | sort -rh | head -20

Bu şekilde katman katman inerek gerçek sorumluyu bulabilirsiniz. Bir keresinde /var/log/mysql dizini 180GB olmuştu. Binary log rotation kapatılmıştı, kimse fark etmemişti. Aylar boyunca birikiyor.

Büyük Dosyaları Bulmak

Dizin bazlı değil, direkt büyük dosyaları bulmak için:

find / -type f -size +100M -exec ls -lh {} ; 2>/dev/null | sort -k5 -rh | head -20

-type f: Sadece dosyaları arar, dizinleri değil -size +100M: 100MB’dan büyük dosyalar -exec ls -lh {} ;: Her bulunan dosya için detaylı liste gösterir

Bu komut biraz yavaş çalışabilir büyük disklerde. Daha hızlı bir alternatif:

find / -xdev -type f -size +100M 2>/dev/null | xargs ls -lh | sort -k5 -rh

-xdev: Farklı mount noktalarına geçmez, sadece mevcut filesystem’de arar

Silinen Ama Hala Yer Kaplayan Dosyalar

Bu senaryo çok kişiyi şaşırtır. Dosyayı sildiniz, df -h hala aynı şeyi gösteriyor. Bunun sebebi: bir process o dosyayı hala açık tutuyor olabilir. Linux’ta dosya silindiğinde, dosyaya olan tüm file descriptor’lar kapanana kadar disk alanı serbest bırakılmaz.

lsof +L1

Bu komut silinmiş ama hala açık tutulan dosyaları listeler. (deleted) yazanlar bizim aradıklarımız. Genellikle büyük log dosyaları bu şekilde yer kaplamaya devam eder. Çözüm ilgili process’i yeniden başlatmak:

systemctl restart uygulama-adi

Ya da dosyanın içeriğini truncate etmek (process’i durdurmak istemiyorsanız):

> /proc/PID/fd/FD_NUMARASI

Burada PID ilgili process’in ID’si, FD_NUMARASI ise lsof çıktısından aldığınız file descriptor numarasıdır.

Hızlı Yer Açma: Güvenli Hedefler

Teşhisi yaptınız, artık temizlik zamanı. En az riskli hedeflerden başlayın.

Log Dosyaları

Log dosyaları çoğunlukla birinci suçludur. Ama dikkatli olun, aktif bir sorunu araştırıyorsanız logları silmek debug sürecinizi mahveder.

# Önce ne kadar yer kaplıyor görelim
du -sh /var/log/

# Eski logları bulmak (30 günden eski)
find /var/log -type f -name "*.log" -mtime +30

# Sıkıştırılmış eski log dosyaları genellikle güvenle silinebilir
find /var/log -type f -name "*.gz" -mtime +7 -delete

# Journal loglarını temizlemek (systemd sistemlerde)
journalctl --disk-usage
journalctl --vacuum-size=500M

journalctl --vacuum-size=500M komutu journal loglarını 500MB’ın altına indirir. Alternatif olarak zaman bazlı temizlik yapabilirsiniz:

journalctl --vacuum-time=7d

Paket Yöneticisi Önbelleği

Yazılım kurulumları sırasında indirilen paketler genellikle önbellekte kalır. Bunlar güvenle temizlenebilir.

Debian/Ubuntu sistemlerde:

apt clean
apt autoclean
apt autoremove --purge

apt clean: Tüm indirilen paket dosyalarını siler apt autoclean: Sadece eski sürümleri siler apt autoremove –purge: Artık ihtiyaç duyulmayan paketleri ve config dosyalarını siler

RHEL/CentOS/Rocky sistemlerde:

yum clean all
dnf clean all

/tmp Dizini

Geçici dosyalar genellikle sistem yeniden başladığında silinir ama uzun süredir kapatılmamış sistemlerde birikiyor.

# Önce ne var görelim
du -sh /tmp/
ls -la /tmp/

# 7 günden eski geçici dosyaları temizle
find /tmp -type f -atime +7 -delete
find /tmp -type d -empty -delete

Temizlemeden önce mutlaka içeriğe bakın. Bazen geliştiriciler /tmp’ye büyük dosyalar kopyalar ve orada unutur.

Daha Derin Temizlik Senaryoları

Docker Artıkları

Docker kullanan sistemlerde disk dolmasının sık sebebi kullanılmayan image, container ve volume’lar.

# Docker disk kullanımı özeti
docker system df

# Çalışmayan container'ları temizle
docker container prune

# Kullanılmayan image'ları temizle
docker image prune -a

# Kullanılmayan volume'ları temizle
docker volume prune

# Hepsini bir anda temizle (dikkatli kullanın!)
docker system prune -a --volumes

docker system prune -a --volumes çok agresif bir komut. Çalışmayan her şeyi siler. Production’da çalışan ama o an stopped durumunda olan container’larınız varsa onları da siler. Önce docker ps -a ile durumu kontrol edin.

MySQL/PostgreSQL Log ve Geçici Dosyalar

Veritabanı sunucuları ciddi disk tüketicileridir.

# MySQL binary log durumu
mysql -e "SHOW BINARY LOGS;"

# Binary logları temizle (dikkatli! replication kullanıyorsanız slave durumunu kontrol edin)
mysql -e "PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);"

# MySQL genel sorgu logunu kontrol et
mysql -e "SHOW VARIABLES LIKE 'general_log%';"

Binary log’ları silmeden önce replication setup’ınız varsa slave’in hangi log pozisyonunda olduğunu kontrol edin. Slave’in henüz okumadığı bir log’u silerseniz replication kırılır.

Core Dump Dosyaları

Crash alan uygulamalar core dump bırakır. Bunlar büyük olabilir ve genellikle gözden kaçar.

find / -name "core" -type f 2>/dev/null
find / -name "core.*" -type f 2>/dev/null
find / -name "*.core" -type f 2>/dev/null

# systemd-coredump kullanan sistemlerde
ls -lh /var/lib/systemd/coredump/
coredumpctl list

Core dump’ları silmeden önce henüz analiz edilmemiş bir crash varsa, geliştirici ekiple konuşun. Core dump debug için altın değerinde olabilir.

İnode Tükenmesi: Farklı Bir Problem

Daha önce bahsettiğim inode sorununa dönelim. df -h boş alan gösteriyor ama dosya oluşturamıyorsunuz. Bu inode tükenmesidir.

df -i

IUse% sütununda 100% görüyorsanız inode sorununuz var demektir. Çözüm çok sayıda küçük dosyayı bulmak ve temizlemek.

# En çok dosya içeren dizinleri bul
find / -xdev -type f 2>/dev/null | awk -F'/' '{print NF-1" "$0}' | sort -rn | head -20

# Belirli bir dizindeki dosya sayısı
find /var/spool/postfix -type f | wc -l

Mail server’larda /var/spool inode tükenmesinin klasik sebebidir. Binlerce küçük mail dosyası birikir. PHP session dosyaları da aynı problemi yaratır.

Acil Durumda Yer Açmak

Hiçbir şeye dokunamıyorsunuz, sadece sistemi ayakta tutmanız gerekiyor. En hızlı çözümler:

# Büyük log dosyalarını truncate et (silmeden, sıfırla)
> /var/log/uygulama.log

# Alternatif
truncate -s 0 /var/log/uygulama.log

Truncate etmek silmekten daha güvenlidir. Dosya var olmaya devam eder, içeriği boşalır. Process hala o dosyaya yazabilir.

Gerçekten kritik bir durumdaysa ve birkaç GB’a ihtiyacınız varsa:

# Büyük geçici dosya sil
rm -f /var/log/uygulama.log.1
rm -f /var/log/uygulama.log.2

# Eski nginx/apache access log'ları
ls -lh /var/log/nginx/
rm -f /var/log/nginx/access.log.gz

Bazı sistem yöneticileri olası acil durumlar için diskte bir “yedek alan” dosyası tutar. Sistemi kurduklarında birkaç GB’lık boş bir dosya oluşturur, gerçek acil durumda silerler:

# Kurulum sırasında
dd if=/dev/zero of=/emergency-space bs=1M count=2048

# Acil durumda
rm -f /emergency-space

Kulağa garip gelebilir ama production sistemlerde gördüm bu yaklaşımı. Mantıklı bir güvenlik ağı.

Düzgün Log Rotation Kurulumu

Acil durumu atlattıktan sonra tekrar yaşanmaması için logrotate konfigürasyonunu düzenleyin.

# Mevcut logrotate konfigürasyonunu kontrol et
cat /etc/logrotate.conf
ls /etc/logrotate.d/

# Test et (gerçekte çalıştırma, sadece simüle et)
logrotate -d /etc/logrotate.conf

# Manuel çalıştır
logrotate -f /etc/logrotate.conf

Özel bir uygulama için logrotate konfigürasyonu yazmak istiyorsanız /etc/logrotate.d/ altına bir dosya oluşturun:

cat > /etc/logrotate.d/uygulamam << 'EOF'
/var/log/uygulamam/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    sharedscripts
    postrotate
        systemctl reload uygulamam > /dev/null 2>&1 || true
    endscript
}
EOF

daily: Her gün rotate et rotate 7: 7 kopyayı sakla, eskisini sil compress: Eski logları gzip ile sıkıştır delaycompress: Bir önceki günün logunu sıkıştırma (aktif yazma olabilir) missingok: Log dosyası yoksa hata verme notifempty: Boş dosyayı rotate etme

İzleme ve Uyarı Sistemi

Bir daha gece 02:30’da telefon alamamak için disk dolmadan önce uyarı almalısınız.

Basit bir bash script ile cron’a ekleyebilirsiniz:

#!/bin/bash
ESIK=85
MAIL="[email protected]"

df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{print $5 " " $1}' | while read output; do
    kullanim=$(echo $output | awk '{print $1}' | cut -d'%' -f1)
    partition=$(echo $output | awk '{print $2}')
    
    if [ $kullanim -ge $ESIK ]; then
        echo "UYARI: $partition %$kullanim dolu" | mail -s "Disk Uyarisi: $(hostname)" $MAIL
    fi
done

Bu script’i /usr/local/bin/disk-kontrol.sh olarak kaydedip cron’a ekleyin:

chmod +x /usr/local/bin/disk-kontrol.sh

# Her saat kontrol et
echo "0 * * * * root /usr/local/bin/disk-kontrol.sh" >> /etc/crontab

Zabbix, Prometheus/Grafana veya Nagios gibi bir monitoring sisteminiz varsa disk alertlerini orada konfigüre etmek çok daha sağlıklı. Ama basit ortamlarda bu script geçici değil, kalıcı çözüm olarak kullanılabilir.

Kalıcı Çözüm: Kapasite Planlaması

Disk sorunları genellikle ani olmaz, yavaş yavaş birikir. Aylık disk büyüme trendini takip etmek, sorunu önceden görmenizi sağlar.

Basit bir trend takibi için:

# Her gün disk kullanımını logla
echo "$(date '+%Y-%m-%d %H:%M') $(df -h / | tail -1)" >> /var/log/disk-trend.log

# Trendi görmek için
tail -30 /var/log/disk-trend.log

30 günlük veriyle aylık büyüme hızını hesaplayabilir ve “bu disk ne zaman dolar” sorusuna cevap verebilirsiniz. Bu veriyi yönetime götürdüğünüzde disk genişletme talebiniz çok daha somut bir zemine oturur.

Fiziksel disk eklemek mümkün değilse ve cloud ortamındaysanız:

# AWS EBS volume genişletme sonrası (partition ve filesystem büyütme)
growpart /dev/xvda 1
resize2fs /dev/xvda1

# LVM kullanıyorsanız
lvextend -L +20G /dev/mapper/ubuntu--vg-ubuntu--lv
resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv

Sonuç

Disk dolması senaryosu streslidir ama sistematik yaklaşıldığında çözümü genellikle hızlıdır. Özetlemek gerekirse:

  • Önce teşhis: df -h, du -sh, find komutlarıyla tam resmi görün
  • Silinen ama açık dosyaları kontrol edin: lsof +L1
  • Güvenli hedeflerden başlayın: Paket cache, geçici dosyalar, eski loglar
  • Truncate, silmekten daha güvenlidir: Aktif dosyalar için > dosya kullanın
  • Acil durumdan sonra kalıcı çözüm: Logrotate, monitoring, kapasite planlaması

Disk dolması bir kez yaşandıktan sonra monitoring kurmazsanız, büyük ihtimalle tekrar yaşarsınız. Acil müdahaleden sonra mutlaka uyarı sistemini devreye alın. Gece 02:30’daki telefon yerine gece yarısından önce gelen bir mail uyarısı, tüm süreci çok daha insancıl hale getirir.

Bir yanıt yazın

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