Linux'ta disk doldu: yer kaplayan dosyaları bulmak ve güvenle temizlemek
"No space left on device" hatası veritabanını durdurabilir, siteyi kapatabilir, hatta SSH ile girişi bile zorlaştırabilir. Paniğe gerek yok, aşağıdaki sırayla ilerle.
1. Gerçekten dolu mu?
df -h
Use% sütunu %100'e yakın olan bölümü bul. Ama bir şey daha kontrol et:
df -i
Bu, inode kullanımını gösterir. Disk boş görünüp yine de "No space left" hatası alıyorsan inode'lar bitmiştir: milyonlarca küçük dosya vardır (genellikle oturum dosyaları, önbellek veya posta kuyruğu).
2. Yer kaplayanı bul
sudo du -xh --max-depth=1 / 2>/dev/null | sort -h
En büyük klasöre gir ve aynı komutu orada tekrarla (/var, sonra /var/log...). -x aynı dosya sisteminde kalmayı sağlar, bağlı diskleri saymaz.
Daha rahat bir yol ncdu:
sudo apt install ncdu # veya: dnf install ncdu
sudo ncdu -x /
Ok tuşlarıyla klasörlerde gezip büyük olanları görürsün.
En büyük dosyalar:
sudo find / -xdev -type f -size +500M -exec ls -lh {} \; 2>/dev/null
3. Sık rastlanan suçlular
Günlükler
journalctl --disk-usage
sudo journalctl --vacuum-size=300M
ls -lhS /var/log | head
Büyümüş bir günlük dosyasını silmek yerine boşalt. Çalışan bir program dosyayı açık tutuyorsa silmek yer açmaz:
sudo truncate -s 0 /var/log/uygulama/buyuk.log
Silinmiş ama hâlâ açık dosyalar
du toplamı ile df sonucu çok farklıysa, silinmiş ama bir işlem tarafından açık tutulan dosyalar vardır:
sudo lsof +L1
Listedeki işlemi (örneğin web sunucusu veya uygulama) yeniden başlatınca yer geri gelir.
Paket önbelleği ve eski çekirdekler
sudo apt clean
sudo apt autoremove --purge
# RHEL tabanlı sistemlerde:
sudo dnf clean all
Docker
Docker, eski imajlar ve durdurulmuş konteynerlerle hızla büyür:
docker system df
docker image prune # etiketsiz imajlar
docker container prune # durmuş konteynerler
docker builder prune # derleme önbelleği
docker system prune -a --volumes çok daha agresiftir: kullanılmayan bütün imajları ve adlandırılmış volume'ları siler. Veritabanı verisi bir volume'daysa kaybedersin. Ne sildiğini bilmeden çalıştırma.
Yedekler ve veritabanı dökümleri
Sunucuda biriken eski .sql, .tar.gz yedekleri sık rastlanan bir sebeptir. Yedeklerin zaten başka bir yerde de olduğundan emin olduktan sonra eski olanları sil, yedek betiğine de bir saklama süresi ekle.
Veritabanı ikili günlükleri
MySQL/MariaDB'de binlog dosyaları (/var/lib/mysql/ içinde mysql-bin.000123 gibi) büyüyebilir. Bunları elle silme; çoğaltma (replication) kullanıyorsan bozulur. Veritabanı içinden PURGE BINARY LOGS BEFORE ... komutunu kullan ve binlog_expire_logs_seconds (veya eski sürümlerde expire_logs_days) ile otomatik süre belirle.
4. Kesinlikle silme
/var/lib/mysql,/var/lib/postgresqlgibi veritabanı veri klasörlerindeki dosyalar/bootiçindeki şu an kullanılan çekirdek (paket yöneticisiyle kaldır)/usr,/lib,/binaltındaki herhangi bir şey
5. Tekrar olmasın
- Günlük sınırı:
/etc/systemd/journald.conf→SystemMaxUse=500M - Uygulama günlükleri için
logrotatekuralı - Yedekler için saklama süresi
- Basit bir izleme: disk %85'i geçince e-posta gönderen küçük bir cron betiği ya da bir izleme aracı
# Örnek: /etc/cron.hourly/disk-uyari
#!/bin/sh
KULLANIM=$(df --output=pcent / | tail -1 | tr -dc '0-9')
[ "$KULLANIM" -ge 85 ] && echo "Disk %$KULLANIM dolu: $(hostname)" | mail -s "Disk uyarısı" sen@ornek.com
(mail komutu için sistemde bir posta aracı kurulu olmalı.)