[TR] Linux’ta df ve du Arasındaki Disk Kullanımı Farkı

[TR] Linux’ta df ve du Arasındaki Disk Kullanımı Farkı

Linux sistemlerinde disk kullanımı kontrol edilirken en çok kafa karıştıran durumlardan biri, df komutunun diski dolu göstermesine rağmen du komutunun çok daha düşük bir kullanım göstermesidir.

Özellikle production ortamlarda bu durum genellikle şu senaryo ile karşımıza çıkar:

Gece monitoring sisteminden “disk dolu” alarmı gelir. Sunucuya bağlanıp ilk olarak df -h komutu çalıştırılır ve root filesystem’in ya da ilgili disk bölümünün neredeyse tamamen dolduğu görülür. Ardından hangi dizinin alan tükettiğini bulmak için du komutları çalıştırılır. Fakat ilginç bir şekilde du çıktısındaki toplam kullanım, df çıktısında görünen kullanım kadar yüksek değildir.

İlk bakışta bu durum bir hata gibi görünebilir. Ancak çoğu zaman ortada bir hata yoktur. Hem df hem de du doğru bilgi verir. Buradaki temel fark, iki komutun disk kullanımını farklı seviyelerden ölçmesidir.

Bu makalede Linux sistemlerinde df ve du komutlarının neyi ölçtüğünü, bu iki komut arasında neden fark oluşabileceğini, silinmiş ama hâlâ açık tutulan dosyaların nasıl disk alanı tüketmeye devam ettiğini ve bu durumun güvenli şekilde nasıl çözülebileceğini detaylı olarak inceleyeceğiz.

df ve du Komutları Neden Farklı Sonuç Gösterir?

Linux’ta disk kullanımını analiz ederken en sık kullanılan iki komut şunlardır:

df -h

ve:

du -sh /

ya da daha kontrollü bir kullanım olarak:

du -xhd1 /

Bu komutlar benzer amaçla kullanılıyor gibi görünse de aslında aynı şeyi ölçmezler.

df, dosya sistemi seviyesinde kullanılan ve boşta kalan blokları gösterir.

du ise dizin ağacını dolaşarak erişebildiği dosyaların boyutlarını toplar.

Bu nedenle df, filesystem’in kendi muhasebe bilgilerine bakarken; du, dosya ve dizin seviyesinde hesaplama yapar.

Bu fark, özellikle silinmiş ancak hâlâ bir process tarafından açık tutulan dosyalarda çok belirgin hale gelir.

df Komutu Nedir ve Ne Ölçer?

df, “disk free” ifadesinin kısaltmasıdır. Linux sistemlerde mount edilmiş dosya sistemlerinin genel disk kullanımını gösterir.

En yaygın kullanım şekli şöyledir:

df -h

Örnek çıktı:

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        50G   47G  3.0G  94% /
/dev/sdb1       200G  150G   50G  75% /data

Burada görülen bilgiler şunlardır:

Filesystem, ilgili disk bölümünü veya dosya sistemini gösterir.

Size, toplam boyutu gösterir.

Used, kullanılan alanı gösterir.

Avail, kullanılabilir boş alanı gösterir.

Use%, kullanım yüzdesini gösterir.

Mounted on, dosya sisteminin hangi dizine mount edildiğini gösterir.

df, dizinleri tek tek taramaz. Yani /var, /home, /opt gibi dizinlerin içindeki dosyaları dolaşıp boyut toplamaz. Bunun yerine kernel’den ve filesystem metadata bilgilerinden yararlanır.

Başka bir ifadeyle df, şu soruya cevap verir:

“Bu filesystem üzerinde toplam kaç blok ayrılmış, kaç blok boşta?”

Bu yüzden df çıktısı, dosya sisteminin gerçek blok tahsisi açısından oldukça güvenilir bir genel görünüm sağlar.

du Komutu Nedir ve Ne Ölçer?

du, “disk usage” ifadesinin kısaltmasıdır. Belirtilen dizin veya dosyaların disk üzerinde ne kadar alan kullandığını hesaplar.

Örneğin:

du -sh /var/log

Bu komut /var/log dizininin toplam disk kullanımını gösterir.

Örnek çıktı:

2.4G    /var/log

Ancak production sistemlerde kök dizini analiz ederken doğrudan şu komutu çalıştırmak her zaman ideal değildir:

du -sh /

Çünkü bu komut tüm alt dizinleri, mount point’leri ve erişilebilir dosyaları dolaşmaya çalışır. Büyük sistemlerde uzun sürebilir ve gereksiz I/O oluşturabilir.

Bunun yerine daha kontrollü bir yaklaşım tercih edilmelidir:

du -xhd1 /

Bu komuttaki parametreler oldukça önemlidir.

-x parametresi, aynı filesystem içinde kalmasını sağlar. Yani başka mount edilmiş disk bölümlerine geçmez.

-h parametresi, çıktıyı insan tarafından okunabilir hale getirir. Örneğin KB, MB, GB gibi değerler gösterir.

-d1 parametresi, sadece ilk seviye dizinleri gösterir. Böylece kök dizin altında hangi ana dizinin ne kadar alan kullandığı daha net görülür.

Örnek çıktı:

4.5G    /usr
2.8G    /var
1.1G    /home
650M    /opt
20K     /root
9.2G    /

Bu çıktı sayesinde disk kullanımının hangi ana dizinde yoğunlaştığı anlaşılabilir.

Ancak burada kritik bir nokta vardır:

du, yalnızca dizin ağacında görebildiği dosyaları hesaplar.

Eğer bir dosya silinmişse, artık dizin ağacında görünmez. Bu nedenle du o dosyayı hesaba katamaz. Fakat bu dosya bir process tarafından hâlâ açık tutuluyorsa, disk alanı serbest bırakılmamış olabilir.

İşte df ve du arasındaki farkın en yaygın sebebi budur.

Linux’ta Dosya Silme Mantığı Nasıl Çalışır?

Bu konuyu doğru anlamak için Linux’ta dosya silme mantığını bilmek gerekir.

Linux’ta bir dosya temel olarak iki önemli bileşene sahiptir:

Directory entry
Inode

Directory entry, dosyanın dizin içindeki görünen adıdır.

Örneğin:

/var/log/nginx/access.log

Bu dosya yolu, dosyanın dizin ağacındaki ismidir.

Inode ise dosyanın asıl metadata bilgisini tutar. Dosyanın sahibi, izinleri, zaman bilgileri ve disk üzerindeki blok referansları inode üzerinden takip edilir.

Bir dosyayı rm komutu ile sildiğinizde, aslında ilk olarak dosyanın directory entry bilgisi kaldırılır.

Örneğin:

rm /var/log/nginx/access.log

Bu işlemden sonra dosya artık /var/log/nginx/ dizininde görünmez.

Yani:

komutu ile baktığınızda access.log dosyasını göremezsiniz.

Ancak eğer Nginx süreci bu dosyayı hâlâ açık tutuyorsa, inode tamamen serbest bırakılmaz. Çünkü dosyaya hâlâ açık bir file descriptor üzerinden erişim vardır.

Bu durumda dosyanın adı silinmiştir, fakat dosyanın disk üzerindeki blokları hâlâ kullanımdadır.

Sonuç olarak:

du bu dosyayı göremez.

ls bu dosyayı göstermez.

Dosya normal dizin yapısında yokmuş gibi görünür.

Ancak df hâlâ bu alanı kullanılıyor olarak gösterir.

Çünkü kernel açısından dosya hâlâ tamamen kapanmamıştır.

Silinmiş Ama Açık Tutulan Dosya Nedir?

Silinmiş ama açık tutulan dosya, dosya sisteminden adı kaldırılmış ancak bir process tarafından hâlâ file descriptor üzerinden kullanılan dosyadır.

Bu durum genellikle şu isimlerle ifade edilir:

Deleted but open file
Orphaned open file
Invisible disk usage
Space leak
Unlinked file still held by process

Bu problem özellikle uzun süre çalışan servislerde sık görülür.

Örneğin:

Nginx
Apache
Tomcat
Java uygulamaları
Node.js servisleri
Docker container’ları
Database servisleri
Log toplayıcı ajanlar
Backup uygulamaları
Monitoring agent’ları

Bu servisler bir log dosyasını açar ve uzun süre boyunca aynı dosyaya yazmaya devam eder. Eğer bu log dosyası manuel olarak silinirse, uygulama bunu her zaman fark etmeyebilir. Uygulama dosyanın adını değil, açık file descriptor’ını kullanmaya devam eder.

Bu nedenle dosya silinmiş olsa bile uygulama aynı inode’a yazmaya devam edebilir.

En Yaygın Senaryo: Büyük Log Dosyasının Silinmesi

Production sistemlerde bu problemin en sık görülen sebebi büyük log dosyalarının manuel olarak silinmesidir.

Örnek bir senaryo düşünelim.

Nginx access log dosyası büyümüş olsun:

/var/log/nginx/access.log

Bu dosya 20 GB boyutuna ulaşmış olabilir. Disk doluluğu alarmı gelir ve hızlıca alan açmak isteyen bir yönetici şu komutu çalıştırır:

rm /var/log/nginx/access.log

İlk bakışta dosya silinmiş gibi görünür.

Kontrol edilir:

ls -lh /var/log/nginx/

Dosya artık görünmez.

Ardından:

du -sh /var/log

komutu çalıştırılır ve /var/log dizininin kullanımının düştüğü görülür.

Ancak:

df -h

komutu çalıştırıldığında disk kullanımının hâlâ düşmediği görülür.

Bu durumda çoğu kişi “Dosyayı sildim ama alan neden geri gelmedi?” sorusunu sorar.

Cevap şudur:

Nginx süreci dosyayı hâlâ açık tutmaktadır.

Dosya adı silinmiştir, ancak inode ve disk blokları hâlâ Nginx process’i tarafından kullanılmaktadır. Bu nedenle alan kernel tarafından serbest bırakılmamıştır.

Disk alanı ancak şu durumlardan biri gerçekleştiğinde geri gelir:

İlgili process dosyayı kapatırsa
Servis yeniden başlatılırsa
Servis log dosyasını yeniden açarsa
Process sonlanırsa
File descriptor serbest bırakılırsa

df Dolu, du Boş Gösteriyorsa İlk Şüphe Ne Olmalı?

Eğer df -h çıktısında disk dolu görünüyor ancak du -xhd1 / ile yapılan analizde bu kullanım görünmüyorsa, ilk kontrol edilmesi gereken şey silinmiş ama açık tutulan dosyalardır.

Bunu anlamanın en etkili yolu lsof komutudur.

Silinmiş Ama Açık Dosyaları Bulmak İçin lsof +L1

Linux’ta açık dosyaları listelemek için lsof komutu kullanılır.

Silinmiş ancak hâlâ açık tutulan dosyaları bulmak için şu komut çalıştırılır:

sudo lsof -nP +L1

Bu komuttaki parametrelerin anlamı şöyledir:

-n, DNS çözümlemesi yapmaz. Bu sayede komut daha hızlı çalışır.

-P, port numaralarını servis isimlerine çevirmeye çalışmaz. Bu da çıktının daha hızlı gelmesini sağlar.

+L1, link count değeri 1’den küçük olan dosyaları listeler. Bu genellikle silinmiş ancak hâlâ açık tutulan dosyaları bulmak için kullanılır.

Örnek çıktı:

COMMAND   PID   USER     FD   TYPE DEVICE   SIZE/OFF NLINK NODE NAME
nginx    1423   root     10w  REG  253,1   524288000     0 1048 /var/log/nginx/access.log (deleted)
java     2201   tomcat   22w  REG  253,1   209715200     0 2341 /tmp/app.log (deleted)

Bu çıktıyı doğru yorumlamak önemlidir.

COMMAND, dosyayı açık tutan uygulama veya process adını gösterir.

PID, ilgili process’in ID bilgisidir.

USER, process’in hangi kullanıcı ile çalıştığını gösterir.

FD, file descriptor bilgisidir.

TYPE, dosya tipini gösterir.

DEVICE, dosyanın bulunduğu cihaz bilgisidir.

SIZE/OFF, dosyanın boyutunu veya offset bilgisini gösterir.

NLINK, dosyanın link count değerini gösterir.

NAME, dosyanın eski yolunu ve durumunu gösterir.

Eğer NAME alanında (deleted) ifadesi varsa, bu dosya sistemden silinmiş ancak process tarafından hâlâ açık tutuluyor demektir.

Örnekte Nginx, silinmiş bir access.log dosyasını hâlâ açık tutmaktadır. Java uygulaması da silinmiş bir /tmp/app.log dosyasını açık tutmaktadır.

Bu dosyalar ls veya du çıktısında görünmez, ancak df üzerinde kullanılan alan olarak görünmeye devam eder.

Büyük Silinmiş Dosyaları Sıralamak

Bazı sistemlerde çok sayıda silinmiş açık dosya olabilir. Bu durumda hangi dosyanın en çok alan tükettiğini bulmak gerekir.

Bunun için şu komut kullanılabilir:

sudo lsof +L1 | awk '{print $7, $0}' | sort -rn

Bu komut, SIZE/OFF alanını öne alarak çıktıyı büyükten küçüğe sıralamaya çalışır.

Daha sade bir başlangıç için önce şu komut kullanılabilir:

sudo lsof -nP +L1

Ardından büyük boyutlu kayıtlar manuel olarak incelenebilir.

Özellikle SIZE/OFF alanında GB seviyesinde değerler varsa, disk alanını tüketen asıl kaynak büyük ihtimalle bu dosyalardır.

Disk Alanı Nasıl Geri Kazanılır?

Silinmiş ama açık tutulan dosyalar tespit edildikten sonra disk alanını geri kazanmak için birkaç yöntem vardır.

Ancak burada dikkat edilmesi gereken en önemli konu şudur:

Her açık dosya güvenli şekilde sıfırlanamaz veya kapatılamaz.

Bu nedenle önce dosyanın ne olduğunu, hangi process tarafından kullanıldığını ve kritik veri içerip içermediğini anlamak gerekir.

Yöntem 1: İlgili Servisi Yeniden Başlatmak

En temiz ve genellikle en güvenli yöntem, dosyayı açık tutan servisi yeniden başlatmaktır.

Örneğin dosyayı Nginx açık tutuyorsa:

sudo systemctl restart nginx

Apache için:

sudo systemctl restart apache2

Tomcat için:

sudo systemctl restart tomcat

Docker container için:

docker restart container_adi

Servis yeniden başlatıldığında ilgili file descriptor kapanır. File descriptor kapandığı için inode üzerindeki son referans da düşer. Böylece kernel, dosyanın kullandığı disk bloklarını serbest bırakır.

Bu yöntemin avantajı temiz ve anlaşılır olmasıdır.

Dezavantajı ise servis restart işleminin kısa süreli kesintiye neden olabilmesidir.

Bu nedenle production sistemlerde servis restart işlemi öncesinde etki analizi yapılmalı, mümkünse bakım penceresi veya uygun zaman tercih edilmelidir.

Yöntem 2: Servise Log Dosyalarını Yeniden Açtırmak

Bazı servislerde tamamen restart yapmak yerine reload işlemi yeterli olabilir.

Örneğin Nginx için:

sudo systemctl reload nginx

veya:

sudo nginx -s reopen

Apache için:

sudo systemctl reload apache2

Bazı uygulamalarda SIGHUP sinyali gönderilerek log dosyalarının yeniden açılması sağlanabilir:

sudo kill -HUP <PID>

Ancak bu davranış her uygulama için geçerli değildir. Bazı uygulamalar SIGHUP sinyalini desteklemez, bazıları ise sadece yapılandırmayı yeniden okur ancak log dosyasını yeniden açmaz.

Bu nedenle bu yöntemi kullanmadan önce ilgili uygulamanın dokümantasyonu veya çalışma davranışı kontrol edilmelidir.

Yöntem 3: /proc Üzerinden File Descriptor’ı Truncate Etmek

Servisi yeniden başlatmanın mümkün olmadığı durumlarda, ilgili file descriptor üzerinden dosya sıfırlanabilir.

Önce problemli dosya tespit edilir:

sudo lsof -nP +L1

Örnek çıktı:

COMMAND   PID   USER   FD   TYPE DEVICE   SIZE/OFF NLINK NODE NAME
nginx    1423   root   10w  REG  253,1   524288000     0 1048 /var/log/nginx/access.log (deleted)

Burada önemli bilgiler şunlardır:

PID değeri:

1423

FD değeri:

10w

FD değerindeki w, dosyanın write modunda açık olduğunu gösterir. /proc altında bu file descriptor’a şu şekilde erişilebilir:

/proc/1423/fd/10

Dosyayı sıfırlamak için şu komut kullanılabilir:

sudo truncate -s 0 /proc/1423/fd/10

Bu işlem dosyanın içeriğini sıfırlar ve disk alanını geri kazandırır.

Bu yöntemin avantajı, servisi durdurmadan alanın geri kazanılabilmesidir.

Ancak dikkatli kullanılmalıdır. Çünkü yanlış dosya üzerinde uygulanırsa veri kaybına veya uygulama tutarsızlığına neden olabilir.

Truncate Kullanırken Nelere Dikkat Edilmeli?

truncate yöntemi her dosyada güvenli değildir.

Genellikle aşağıdaki tipteki dosyalar için güvenli kabul edilebilir:

Web server access log dosyaları
Web server error log dosyaları
Debug log dosyaları
Geçici uygulama logları
Text formatındaki sıradan log dosyaları

Ancak aşağıdaki dosyalarda kesinlikle dikkatli olunmalıdır:

Database WAL dosyaları
MySQL binary log dosyaları
PostgreSQL transaction log dosyaları
Oracle redo log dosyaları
Queue dosyaları
Crash recovery dosyaları
Aktif veri dosyaları
State dosyaları
Binary formatlı uygulama dosyaları

Bu tür dosyaları truncate etmek veri kaybına, uygulama bozulmasına veya servislerin tutarsız çalışmasına neden olabilir.

Ayrıca bazı uygulamalar dosya truncate edildikten sonra beklenmedik davranış gösterebilir. Çünkü uygulama file offset bilgisini koruyarak yazmaya devam edebilir. Dosya sıfırlanmış olsa bile process, dosyanın eski yazma pozisyonundan devam etmeye çalışabilir.

Bu durum özellikle bazı Java logger implementasyonlarında, özel Go logging mekanizmalarında ve stateful çalışan uygulamalarda sorun yaratabilir.

Bu nedenle truncate işlemi uygulanmadan önce mutlaka şu sorular sorulmalıdır:

Bu dosya gerçekten sadece log dosyası mı?

Dosya kritik veri içeriyor mu?

Servis restart edilebilir mi?

Reload ile log dosyası yeniden açtırılabilir mi?

Bu işlem uygulama davranışını etkiler mi?

df ve du Farkının Diğer Sebepleri

Her df ve du farkı silinmiş açık dosyalardan kaynaklanmaz. Bazı farklı durumlar da bu farkı oluşturabilir.

1. Reserved Blocks

ext4 gibi dosya sistemlerinde belirli bir alan root kullanıcısı için rezerve edilir.

Bu alan genellikle sistemin tamamen kilitlenmesini önlemek için ayrılır. Varsayılan oran çoğu sistemde yaklaşık yüzde 5 olabilir.

Bu rezerv alan normal kullanıcılar tarafından kullanılamaz. Bu nedenle df çıktısında kullanılabilir alan beklenenden daha düşük görünebilir.

Reserved block bilgisini görmek için:

sudo tune2fs -l /dev/sdX | grep -i reserved

Örnek:

sudo tune2fs -l /dev/sda1 | grep -i reserved

Örnek çıktı:

Reserved block count:     655360
Reserved blocks uid:      0
Reserved blocks gid:      0

Büyük disklerde yüzde 5 rezerv alan ciddi bir boyuta denk gelebilir. Örneğin 2 TB bir filesystem üzerinde yüzde 5 rezerv alan yaklaşık 100 GB eder.

Reserved block oranı değiştirilebilir, ancak bu işlem dikkatli yapılmalıdır. Özellikle root filesystem üzerinde çok düşük rezerv bırakmak, sistem servislerinin disk tamamen dolduğunda çalışamamasına neden olabilir.

2. Gizli Mount Point İçerikleri

Bir dizin üzerine yeni bir filesystem mount edildiğinde, o dizinin altında önceden bulunan eski veriler görünmez hale gelir.

Örneğin /data dizininde daha önce dosyalar olduğunu düşünelim:

/data/eski_dosyalar

Daha sonra /data üzerine başka bir disk mount edilirse:

mount /dev/sdb1 /data

Bu durumda /data dizininin eski içeriği görünmez. Çünkü artık /data altında yeni mount edilen filesystem görünmektedir.

Ancak eski dosyalar root filesystem üzerinde hâlâ alan tüketiyor olabilir.

Bu tip durumlar özellikle manuel mount işlemleri, yanlış fstab yapılandırmaları veya sonradan eklenen disklerde karşımıza çıkabilir.

Mount yapılarını kontrol etmek için:

findmnt

veya:

mount

komutları kullanılabilir.

Ayrıca block device ve mount ilişkisini görmek için:

lsblk

komutu da oldukça faydalıdır.

3. Sparse Dosyalar

Sparse dosyalar, görünen boyutu büyük olmasına rağmen fiziksel olarak daha az disk alanı tüketen dosyalardır.

Örneğin bir sanal disk imajı 100 GB görünebilir ancak gerçek disk kullanımı 15 GB olabilir.

Bunu görmek için iki farklı du çıktısı karşılaştırılabilir:

du -sh file.img

ve:

du -sh --apparent-size file.img

du -sh file.img, dosyanın fiziksel olarak diskte kapladığı alanı gösterir.

du -sh --apparent-size file.img, dosyanın mantıksal yani görünen boyutunu gösterir.

Bu durum özellikle şu dosyalarda sık görülür:

Sanal makine diskleri
Database dosyaları
Backup imajları
QCOW2 dosyaları
Raw image dosyaları
Log veya test amaçlı oluşturulmuş büyük dosyalar

Sparse dosyalar doğrudan df ve du farkının tek sebebi olmayabilir, ancak disk analizi sırasında yanlış yorumlamaya neden olabilir.

4. Container ve OverlayFS Katmanları

Docker, Podman veya Kubernetes kullanılan sistemlerde disk kullanımı daha karmaşık hale gelir.

Container teknolojileri overlay filesystem katmanları, image cache’leri, volume’ler ve container logları ile çalışır.

Bu nedenle host üzerinde disk doluluğu yaşandığında klasik du kontrolleri bazen yeterli olmayabilir.

Docker disk kullanımını görmek için:

docker system df

Daha detaylı çıktı için:

docker system df -v

Container logları genellikle şu dizin altında bulunur:

/var/lib/docker/containers/

Özellikle varsayılan json-file log driver kullanılıyorsa, container log dosyaları zaman içinde çok büyüyebilir.

Bu dosyaları manuel olarak silmek yerine Docker log rotation yapılandırması yapılmalıdır.

Örnek /etc/docker/daemon.json yapılandırması:

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

Bu yapılandırmadan sonra Docker servisi yeniden başlatılmalıdır:

sudo systemctl restart docker

Bu ayar sayesinde her container log dosyası belirli bir boyutu aşınca rotate edilir ve eski log sayısı sınırlandırılır.

5. Inode Tükenmesi

Bazen problem disk alanı değil, inode tükenmesidir.

Linux dosya sistemlerinde her dosya ve dizin bir inode kullanır. Çok sayıda küçük dosya oluşturulan sistemlerde disk alanı hâlâ boş olsa bile inode sayısı tükenebilir.

Inode kullanımını kontrol etmek için:

df -i

Örnek çıktı:

Filesystem      Inodes  IUsed   IFree IUse% Mounted on
/dev/sda1      3276800 3200000  76800   98% /

Eğer IUse% değeri çok yüksekse, sistem yeni dosya oluşturamayabilir.

Bu durum özellikle şu dizinlerde sık görülür:

Mail queue dizinleri
Cache dizinleri
Session dosyaları
Geçici upload dizinleri
Küçük log parçaları
Container overlay dizinleri

Inode problemi ile disk alanı problemi birbirine karıştırılmamalıdır. Bu nedenle disk doluluğu analizinde df -h ile birlikte mutlaka df -i de kontrol edilmelidir.

Production Ortamlarında Disk Dolu Alarmı Geldiğinde İzlenecek Yol

Bir Linux sunucuda disk doluluğu alarmı aldığınızda rastgele dosya silmek yerine kontrollü bir analiz yapılmalıdır.

Aşağıdaki sıra pratik ve güvenli bir kontrol akışı sağlar.

Önce genel disk kullanımını kontrol edin:

df -h

Ardından inode kullanımını kontrol edin:

df -i

Hangi filesystem’in dolduğunu belirleyin. Örneğin root filesystem doluysa:

du -xhd1 /

Eğer /var büyük görünüyorsa:

du -xhd1 /var

Eğer /var/log büyük görünüyorsa:

du -xhd1 /var/log

Eğer df yüksek kullanım gösteriyor ancak du ile bu alan görünmüyorsa:

sudo lsof -nP +L1

Docker kullanılıyorsa:

docker system df

Büyük dosya aramak için:

find / -xdev -type f -size +1G -exec ls -lh {} \;

Bu komut sadece aynı filesystem içinde 1 GB’tan büyük dosyaları listeler.

Son olarak mount yapılarını kontrol edin:

findmnt

ve:

lsblk

Bu adımlar sayesinde problemli alanın gerçekten hangi katmanda olduğu anlaşılabilir.

Büyük Log Dosyalarını Silmek Yerine Ne Yapılmalı?

Production sistemlerde büyük log dosyalarını doğrudan rm ile silmek genellikle doğru bir yöntem değildir.

Yanlış yaklaşım:

rm /var/log/nginx/access.log

Bu komut dosyayı dizinden kaldırır ancak servis dosyayı açık tutuyorsa alan geri gelmeyebilir.

Daha doğru yaklaşım, dosyayı silmeden içeriğini sıfırlamaktır:

sudo truncate -s 0 /var/log/nginx/access.log

Bu işlem dosyanın inode’unu değiştirmez, sadece içeriğini sıfırlar. Uygulama aynı dosyaya yazmaya devam edebilir.

Ancak uzun vadede en doğru çözüm logrotate yapılandırmasının düzgün yapılmasıdır.

Logrotate Yapılandırması Neden Önemlidir?

Logrotate, Linux sistemlerde log dosyalarının kontrolsüz büyümesini engelleyen en önemli mekanizmalardan biridir.

Doğru yapılandırılmış bir logrotate sistemi sayesinde:

Log dosyaları belirli aralıklarla döndürülür.

Eski loglar sıkıştırılır.

Belirli sayıdan fazla eski log tutulmaz.

Servislere log dosyalarını yeniden açmaları için sinyal gönderilebilir.

Disk doluluğu riski azaltılır.

Örnek bir Nginx logrotate yapılandırması şu şekilde olabilir:

/var/log/nginx/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        systemctl reload nginx > /dev/null 2>&1 || true
    endscript
}

Bu yapılandırmada:

daily, logların günlük rotate edileceğini belirtir.

rotate 14, 14 adet eski log tutulacağını belirtir.

compress, eski logların sıkıştırılacağını belirtir.

delaycompress, son rotate edilen dosyanın bir sonraki turda sıkıştırılmasını sağlar.

missingok, log dosyası yoksa hata verilmesini engeller.

notifempty, boş log dosyalarının rotate edilmesini engeller.

create, yeni log dosyasının hangi izin ve sahiplikle oluşturulacağını belirtir.

postrotate, rotate işleminden sonra çalıştırılacak komutları belirtir.

Bu sayede log dosyaları düzenli şekilde yönetilir ve disk doluluğu problemleri büyük ölçüde azaltılır.

Hangi Durumda Hangi Komut Kullanılmalı?

DurumKullanılacak KomutAçıklama
Genel disk kullanımını görmekdf -hFilesystem bazlı kullanılan ve boş alanı gösterir.
Inode kullanımını görmekdf -iInode tüketimini kontrol eder.
Kök dizinde büyük alanları bulmakdu -xhd1 /Aynı filesystem içinde ilk seviye dizinleri gösterir.
/var altında büyük alanları bulmakdu -xhd1 /var/var altındaki büyük dizinleri listeler.
Silinmiş ama açık dosyaları bulmaksudo lsof -nP +L1Deleted ama hâlâ process tarafından açık tutulan dosyaları gösterir.
Büyük dosyaları bulmakfind / -xdev -type f -size +1G -exec ls -lh {} \;Aynı filesystem içinde 1 GB’tan büyük dosyaları bulur.
Docker disk kullanımını görmekdocker system dfImage, container, volume ve build cache kullanımını gösterir.
Docker detaylı kullanım görmekdocker system df -vDocker disk kullanımını detaylı gösterir.
Mount yapılarını görmekfindmntHangi filesystem’in nereye mount edildiğini gösterir.
Disk ve partition yapısını görmeklsblkBlock device, disk ve partition yapısını gösterir.
Sparse dosya kontrolü yapmakdu -sh file ve du -sh --apparent-size fileFiziksel kullanım ile görünen boyutu karşılaştırır.
ext4 reserved block kontrolütune2fs -l /dev/sdXReserved block bilgilerini gösterir.

Örnek Olay Analizi

Bir sunucuda monitoring sistemi root filesystem’in yüzde 95 dolduğunu bildirsin.

İlk kontrol:

df -h

Çıktı:

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        50G   48G  2.0G  96% /

Ardından dizin bazlı kontrol:

du -xhd1 /

Çıktı:

5.0G    /usr
3.0G    /var
1.5G    /home
500M    /opt
10G     /

Burada dikkat edilmesi gereken nokta şudur:

df, 48 GB kullanım gösteriyor.

du, toplamda yaklaşık 10 GB kullanım gösteriyor.

Bu iki değer arasında ciddi fark vardır.

Bu durumda silinmiş ama açık dosya ihtimali yüksektir.

Kontrol edilir:

sudo lsof -nP +L1

Örnek çıktı:

COMMAND   PID   USER   FD   TYPE DEVICE   SIZE/OFF NLINK NODE NAME
java     2450   app    12w  REG  253,1   32212254720  0 123456 /var/log/app/application.log (deleted)

Burada Java uygulamasının silinmiş bir log dosyasını hâlâ açık tuttuğu görülmektedir. Dosya yaklaşık 30 GB alan tüketmektedir.

Çözüm seçenekleri:

Uygulama restart edilebilir:

sudo systemctl restart app-service

veya kesinti istenmiyorsa ve dosyanın sadece log dosyası olduğundan eminsek:

sudo truncate -s 0 /proc/2450/fd/12

İşlem sonrası tekrar kontrol edilir:

df -h

Disk alanının geri geldiği görülür.

Bu Problemi Önlemek İçin Alınabilecek Önlemler

Bu tür disk doluluğu problemlerini tamamen ortadan kaldırmak her zaman mümkün olmasa da doğru yapılandırmalarla büyük ölçüde azaltmak mümkündür.

Önerilen önlemler şunlardır:

Logrotate yapılandırmaları düzenli kontrol edilmelidir.

Uygulama logları için maksimum dosya boyutu belirlenmelidir.

Docker container logları için max-size ve max-file ayarlanmalıdır.

Monitoring sistemlerinde sadece disk yüzdesi değil inode kullanımı da takip edilmelidir.

/var/log, /tmp, /var/lib/docker gibi alanlar ayrıca izlenmelidir.

Uygulamaların log dosyalarını rotate sonrası yeniden açabildiği doğrulanmalıdır.

Büyük log dosyaları doğrudan rm ile silinmemelidir.

Production ortamlarında disk temizliği için standart operasyon prosedürü oluşturulmalıdır.

Belirli aralıklarla lsof +L1 kontrolü yapılabilir.

Linux sistemlerinde df ve du komutları disk kullanımını farklı seviyelerden ölçer.

df, filesystem seviyesinde ayrılmış bloklara bakar.

du, dizin ağacında erişilebilen dosyaların boyutlarını toplar.

Bu nedenle iki komutun çıktısının her zaman aynı olması beklenmez.

Özellikle silinmiş ancak hâlâ bir process tarafından açık tutulan dosyalar, df ve du arasında ciddi farklara neden olabilir. Bu dosyalar dizin içinde görünmez, ls ile listelenmez ve du tarafından hesaplanmaz. Ancak kernel açısından hâlâ açık oldukları için disk blokları serbest bırakılmaz.

Bu durumu tespit etmek için en etkili komut şudur:

sudo lsof -nP +L1

Problemi çözmek için en güvenli yöntem genellikle ilgili servisi yeniden başlatmak veya servise log dosyalarını yeniden açtırmaktır. Servis kesintisi istenmeyen durumlarda, dosyanın sıradan bir log dosyası olduğundan emin olunarak /proc/PID/fd/FD üzerinden truncate işlemi uygulanabilir.

Disk doluluğu problemlerinde rastgele dosya silmek yerine, alanın hangi katmanda tutulduğunu doğru analiz etmek gerekir. Çünkü Linux’ta disk kullanımı yalnızca “hangi dizin kaç GB?” sorusundan ibaret değildir. Asıl önemli olan, disk bloklarının gerçekten hangi process, hangi inode veya hangi filesystem davranışı nedeniyle kullanımda olduğunu anlayabilmektir.

Doğru analiz için df, du, lsof, findmnt, df -i ve container kullanılan ortamlarda docker system df komutları birlikte değerlendirilmelidir. Bu yaklaşım, production sistemlerde hem hızlı hem de güvenli müdahale yapılmasını sağlar.