deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak dev.to (home feed)

df -h boş alan gösterdiği hâlde yazma işlemleri başarısız oluyor: inode tükenmesi için saha rehberi

Bir dev.to hata ayıklama notu, df -h hâlâ boş alan bildirirken küçük yazma işlemlerinin neden ENOSPC ile başarısız olabileceğini ve df -i komutunun gerçek suçluyu, inode tükenmesini nasıl ortaya çıkardığını anlatıyor.

df -h boş alan gösterdiği hâlde yazma işlemleri başarısız oluyor: inode tükenmesi için saha rehberi

Dolu bir diske benzeyen bir yazma hatası

dev.to'da yayımlanan bir yazıya göre bir geliştirici, dolu bir disk gibi davranan ama aslında öyle olmayan bir yazma hatasını ayıklamak için yaklaşık iki gün harcadı. Her çalışmanın yanına bir JSON yan dosyası bırakan küçük bir Python worker'ı, df -h kök dosya sisteminde bol miktarda boş alan bildirirken ve /tmp da aynı şekilde sakin görünürken OSError: [Errno 28] No space left on device hatasıyla başarısız olmaya başladı. Ev dizininde elle yapılan bir touch işlemi bile başarılı oldu; yazar bunu, worker'ın yolunun bir şekilde özel olduğuna dair bir kanıt olarak gördü.

O başarılı deneme tam bir tuzaktı. Yazıda açıklandığı gibi, bir dosya sistemi bir dizindeki dosyayı kabul ederken başka bir dizindeki küçük bir yazmayı reddedebilir; çünkü depolama blokları ve inode'lar ayrı limitlerdir. Yazar, belirtiyi bir alan sorunu olarak ele alıp bu varsayımı sorgulamadan önce yaklaşık on iki saat harcadı.

İşleri daha da kötüleştiren temizlik

İlk tur düzeltmeler bilinen operatör içgüdülerini izledi: logların içini boşaltmak, du -sh ile ortaya çıkan büyük dosyaları silmek ve sızmış bir geçici dosya söz konusuysa diye süreci yeniden başlatmak. Bunların hiçbiri işe yaramadı. Durum daha sonra, her dosyayı silmeden önce bir .trash dizinine kopyalayan iyi niyetli bir "güvenli silme" yardımcısı yüzünden kötüleşti. Küçük JSON dosyaları için kopyalamak bayt olarak neredeyse hiçbir şey表达 etmez ama iki kopya da varken fazladan bir inode tüketir; yani düzenli yapmak dosya sistemini inode tavanına biraz daha yaklaştırdı.

Python araç zinciri sorunu daha da büyüttü. __pycache__ ağaçları, pytest önbellek dizinleri ve editör swap dosyaları du -sh çıktısında asla büyük görünmez; çünkü tek bir büyük log yerine binlerce küçük girdiden oluşurlar — inode'ları tam da tüketen profil budur.

Soruyu yanıtlayan komut

Yaklaşık yirminci saatte yazar sonunda blok kullanımı yerine inode kullanımını bildiren df -i komutunu çalıştırdı ve mount noktasının fiilen inode'lardan mahsur kaldığını gördü. Gerçek kısıt görünür olduğunda, sıradan araçlar suçluları belirledi:

  • find komutunu awk, sort ve uniq -c ile boru hattına bağlayarak dizin başına dosya saymak en gürültülü klasörleri ortaya çıkardı; bunlar da loglar değil, önbellekler ve yan dosyalar oldu.
  • Bir uzantı histogramı hangi dosya türlerinin baskın olduğunu gösterdi.
  • __pycache__, .pytest_cache ve .mypy_cache gibi bilinen önbellek dizini adlarını aramak klasik küçük dosya yuvalarını nokta atışı buldu.

Bir laboratuvar ve bir tanılama betiği

Yazı iki artefakt sunuyor. İlki, okuyucuların laboratuvarı silmeden önce df -i değerinin yükselişini izlemesini sağlayan, 20.000 küçük JSON dosyasını kullanılmayacak bir dizine yazan bir demonstrasyon betiği. Açık bir --i-understand bayrağı olmadan çalışmayı reddediyor ve production testi değil yerel bir demonstrasyon olarak etiketleniyor.

İkincisi, yazarın artık donanımı suçlamadan önce çalıştırdığı salt okunur bir tanılama betiği. Sabit bir sırayla dört ayrı tavanı kontrol ediyor: df -h ile blok kullanımı, df -i ile inode kullanımı, başarısız olan yolda bir dosyanın gerçekten oluşturulup oluşturulamayacağını görmek için bir touch denemesi ve girdi sayısına göre ölçülen dizin yoğunluğu; ayrıca lsof ve ulimit -n ile açık dosya toplamları. Betik gözlemleri yazdırıyor ve hiçbir onarım girişiminde bulunmuyor.

Yazar ayrıca bu hatanın bir kuzenine dikkat çekiyor: içinde o kadar çok girdi olan bir dizin ki ls askıda kalıyor gibi görünür; bu dosya sistemi genelinde inode tükenmesi değildir ama asıl kısıt baytlar değil dosya girdileriyken baytları takip etme hatasından doğar.

Neden önemli

ENOSPC yalnızca blokların tükendiği anlamına gelmez. Çok sayıda küçük dosya üreten iş yükleri — yan dosyalar, önbellekler, istek başına artefaktlar — bir diski doldurmadan çok önce inode'ları tüketebilir ve silmeden önce kopyalayan temizlik rutinleri bu başarısızlığı hızlandırabilir. dev.to yazısından pratik ders, gizemli her yazma hatasının başında df -h komutunu df -i ile birlikte çalıştırmaktır; çünkü bu iki komut farklı sorulara yanıt verir — ayrıca dizinleri yalnızca boyuta göre değil dosya sayısına göre de profillemektir.

  • #linux
  • #debugging
  • #filesystems
  • #sysadmin
  • #shell

İlgili yazılar