← blog · 12 Ekim 2026

Disk Doldu Dediğinde Neyin Dolduğunu Bulmak: inode, Silinmiş Ama Açık Dosyalar ve Ayrılmış Bloklar

"Disk doldu" en az üç ayrı duruma karşılık gelir: bloklar, inode'lar ve root'a ayrılmış alan. Üçünün belirtisi aynı, çözümü farklı. Silmeden önce ölçmenin yolları.

Bir sunucuda "disk doldu" alarmı çaldığında ilk refleks en büyük dizini bulup bir şeyler silmek olur. Bu refleks zamanın yarısında işe yaramaz, çünkü "dolu" kelimesi en az üç ayrı duruma karşılık gelir: veri blokları bitmiş olabilir, inode'lar bitmiş olabilir, ya da blokların bir kısmı root kullanıcısına ayrıldığı için uygulama çoktan yazamaz hale gelmiş olabilir. Üçünün belirtisi aynıdır, çözümü farklıdır. Bu yazı doluluğun hangi cinsten olduğunu ayırt etmeye ve silmeden önce ölçmeye odaklanıyor.

Önce hangi doluluk olduğunu ölçün

Blok doluluğu df -h ile, inode doluluğu df -i ile görünür. İkinci komut çoğu teşhis akışında hiç çalıştırılmaz ve bu yüzden de en çok vakit kaybettiren durum inode tükenmesidir: df -h yüzde 40 boş gösterirken yazma işlemi "No space left on device" ile düşer. Küçük dosya üreten iş yükleri (oturum dosyaları, mail kuyruğu, önbellek parçaları, milyonlarca küçük nesne) blokları tüketmeden inode'ları tüketir. ext4'te inode sayısı dosya sistemi oluşturulurken sabitlenir ve sonradan büyütülemez, yani çözüm silmek ya da dosya sistemini yeniden oluşturmaktır. XFS inode'ları dinamik ayırır ve bu sınıf arızayı büyük ölçüde ortadan kaldırır; küçük dosya sayısının yüz binleri aştığı bir bölüm planlıyorsanız bu tek başına dosya sistemi seçimi için yeterli bir gerekçedir.

Üçüncü durum daha sinsidir. ext2, ext3 ve ext4 varsayılan olarak blokların yüzde 5'ini ayrılmış tutar; bu alan yalnızca root tarafından kullanılabilir. Amacı iyidir, parçalanmayı azaltır ve dolu bir diskte yöneticiye hareket alanı bırakır. Sonucu ise şudur: df yüzde 100 demeden önce, root olmayan kullanıcı adına çalışan servis yazmayı bırakır. Veri bölümlerinde bu rezervin 20 TB'lık bir diskte bir terabayta yaklaştığını da hesaba katın. Veri için ayrılmış bir bölümde tune2fs -m 1 /dev/sdX makul bir ayardır; kök bölümde rezervi sıfıra indirmek ise sonradan toparlama şansınızı yok eder.

df ile du neden farklı söyler

Teşhiste en sık görülen çelişki df ile du arasındaki fark. du dizin ağacını dolaşarak görünen dosyaları toplar, df dosya sisteminin kendi muhasebesini okur. Fark üç nedenden doğar.

Birincisi silinmiş ama hâlâ açık dosyalar. Bir süreç bir dosyayı açıkken dosya unlink edilirse dizin girdisi gider, du onu artık görmez, ama bloklar son açık tanımlayıcı kapanana kadar serbest kalmaz. Klasik örnek, log dosyasının rotasyon yerine rm ile silinmesi ve servisin aynı tanımlayıcıya yazmaya devam etmesidir. Bulma yolu lsof +L1 çıktısıdır: NLINK değeri sıfır olan satırlar tam olarak bunlardır. Çözüm silmek değil, dosyayı tutan sürece sinyal vermek ya da onu yeniden başlatmaktır. Acil durumda : > /proc/<pid>/fd/<n> ile dosyayı yerinde boşaltmak alan kazandırır, ama bu geçici bir müdahaledir ve kök neden rotasyon yapılandırmasındadır.

İkincisi gölgelenmiş mount noktaları. Bir dizine bir şey mount edilmişse, mount edilmeden önce o dizine yazılmış dosyalar yer tutmaya devam eder ama hiçbir yerden görünmez. Bunu ölçmenin yolu dosya sistemini başka bir yere bind mount edip oraya bakmaktır:

mkdir -p /mnt/kok
mount --bind / /mnt/kok
du -xh --max-depth=1 /mnt/kok

Üçüncüsü du komutunun dosya sistemi sınırını geçmesi. -x bayrağı olmadan başka bir diskteki ya da ağ üzerindeki dizinleri de sayar ve toplam anlamsız çıkar.

Konteyner çalıştıran makinede doluluk nereye gider

Konteyner çalıştıran bir makinede büyüyen şey genelde uygulamanın veri dizini değil, üç ayrı birikimdir: imaj katmanları, konteyner logları ve isimsiz veri birimleri. docker system df -v bu üçünü ayrı ayrı gösterir ve "hangisini temizlesem" sorusunun tek doğru cevap yeri burasıdır.

Loglar varsayılan olarak sınırsız büyür. Bir servis saniyede birkaç satır bastığında bu haftalar içinde gigabaytlara ulaşır. Doğru çözüm log sürücüsüne sınır koymaktır; günlük dosyaları elle silmek, yukarıda anlatılan "silinmiş ama açık dosya" durumunu üretir:

{
  "log-driver": "json-file",
  "log-opts": { "max-size": "50m", "max-file": "5" }
}

Veri birimleri tarafında dikkatli olun. Kullanılmayan birimleri toptan silen komutlar, o anda ayakta olmayan bir servisin verisini de kullanılmıyor sayar. Bir birim gerçekten sahipsiz mi, önce onu kanıtlayın; toptan temizlik komutunu alışkanlık haline getirmek, bir gün durdurulmuş bir veritabanının diskini silmekle sonuçlanır.

systemd journal de aynı mantıkla sınırlanır. journalctl --disk-usage ile ölçün, kalıcı sınır için SystemMaxUse değerini yapılandırın, acil alan için journalctl --vacuum-size=200M çalıştırın.

Eşik, kota ve ayrı bölüm arasında seçim

Doluluğa karşı üç farklı savunma var ve üçü birbirinin yerine geçmez.

Alarm eşiği en ucuzudur ama tek başına yetersizdir: yüzde 90'da uyarı veren bir alarm, saatte yüzde 5 büyüyen bir log için çok geç kalır. Kullanılabilir alanın mutlak değerine ve büyüme hızına bakan bir kural daha iyi davranır: "iki saat içinde dolacak" bilgisi, "yüzde 90 dolu" bilgisinden daha eyleme dönüktür.

Disk kotası, çok kullanıcılı ya da çok kiracılı sistemlerde tek bir hesabın bütün diski tüketmesini engeller. Bedeli işletme karmaşıklığıdır ve kota aşıldığında uygulamanın verdiği hata mesajı genelde anlaşılmazdır.

Ayrı bölüm, kanaatimce üçünün en etkilisi. Logları, veritabanını, konteyner katmanlarını ve kök dosya sistemini ayrı bölümlere koyan bir düzende tek bir bileşenin taşması makineyi boot edilemez hale getirmez. Bu düzenin maliyeti baştan planlama ve biraz atıl alandır, karşılığında ise arızanın yarıçapını küçültür. Hepsini tek bölüme koyup eşiğe güvenmek, bütün yumurtaları aynı sepete koyup sepeti tartmaktır.

Tuzaklar

Doluluk krizlerinde tekrar eden birkaç tuzak var. En büyük dosyayı silmek, dosya başka bir süreç tarafından açıksa alanı geri getirmez. Yüzde 100 dolu bir diskte bazı veritabanları yazmayı kesmekle kalmaz, kurtarma için de alana ihtiyaç duyar: boş alan yaratmadan servisi yeniden başlatmak kurtarmayı uzatır. Sparse dosyalar (seyrek dosyalar) du ile ls -l arasında büyük fark gösterir ve sanal makine diskleri genelde böyledir. Snapshot alan dosya sistemlerinde silinen veri, snapshot tutulduğu sürece yer kaplamaya devam eder; orada silmek değil, snapshot'ı kaldırmak alan açar. Son olarak /tmp bir tmpfs ise oradaki dosyalar diski değil belleği tüketir, yani belirtileri disk değil bellek tarafında aranır.

Ne zaman bu işe hiç girmemek gerek

Tek seferlik bir doluluk olayını araştırmaya değer kılan şey tekrar etme ihtimalidir. Bir defaya mahsus büyük bir dosya bırakıldıysa ve büyüme kaynağı belliyse, kota ve bölüm planına girmeden o kaynağı düzeltmek yeterli. Asıl yatırım yapılması gereken yer, aynı alarmın ikinci kez çaldığı andır: o noktada çözüm silmek değil, büyümenin sınırlandığı bir yapı kurmaktır.

[ ← burak.sh'a dön ]