Inode Kullanımı Nasıl Ücretsiz?


275

Burada inode kullanımı% 100 ( df -ikomut kullanarak ) olan bir disk sürücüsü var . Ancak, dosyaları önemli ölçüde sildikten sonra kullanım% 100 olarak kalır.

Peki bunu yapmanın doğru yolu nedir?

Daha az disk alanı kullanan bir disk sürücüsünün daha yüksek disk alanı kullanan disk sürücüsüne göre daha yüksek Inode kullanımına sahip olması nasıl mümkün olabilir?

Kullanılan inode sayısını azaltacak çok fazla dosya sıkıştırmam mümkün mü?


4
Bu soru için size 50 puan vermek istiyorum. Nasıl yapabilirim! :)
Sophy

@Sophy Bunu yapma. otomatik olarak yasaklanacaksınız
Steven Lu

1
@StevenLu Bilginiz için teşekkür ederiz! Ona kredi vermek istiyorum çünkü sorunumu çözmek için birkaç gün geçirdim. Ama bu sorun bana yardımcı olabilir. Tekrar teşekkürler,
Sophy

1
@Sophy: Neden SO'ya konu dışı bir şey verdiniz? :) Bu kaç programlama olursa olsun, kesinlikle bir programlama sorusu değildir.
tink

Boş dizinler de inode tüketir. Bunları silmek bazı düğümleri serbest bırakabilir. Sayı bazı kullanım durumlarında önemli olabilir. Boş dizinleri: find ile silebilirsiniz. tipi d
Ruchit Patel

Yanıtlar:


170

Disk dolu olmasa bile bir diskin çok sayıda inot kullanması oldukça kolaydır.

Bir dosyaya bir inode tahsis edilir, bu nedenle, her biri 1 baytın tamamı varsa, diskiniz bitmeden çok önce inode'unuz tükenir.

Dosyaların birden çok sabit bağlantısı varsa, dosyaları silmenin inode sayısını azaltmaması da mümkündür. Söylediğim gibi, inodes dizin girdisine değil dosyaya aittir . Bir dosyanın kendisine bağlı iki dizin girişi varsa, birini silmek inode'u serbest bırakmaz.

Ayrıca, bir dizin girdisini silebilirsiniz, ancak çalışan bir işlemde hala dosya açıksa, inode serbest bırakılmaz.

İlk tavsiyem, yapabileceğiniz tüm dosyaları silmek, ardından dosyaları açık tutarak hiçbir işlem kalmamasını sağlamak için kutuyu yeniden başlatmak olacaktır.

Bunu yaparsanız ve hala bir sorununuz varsa, bize bildirin.

Bu arada, çok sayıda dosya içeren dizinleri arıyorsanız, bu komut dosyası yardımcı olabilir:

#!/bin/bash
# count_em - count files in all subdirectories under current directory.
echo 'echo $(ls -a "$1" | wc -l) $1' >/tmp/count_em_$$
chmod 700 /tmp/count_em_$$
find . -mount -type d -print0 | xargs -0 -n1 /tmp/count_em_$$ | sort -n
rm -f /tmp/count_em_$$

12
Tabii ki, >/tmp/count_em_$$sadece bunun için yeriniz varsa işe yarayacak ... eğer durum buysa, @ simon'un cevabına bakın.
alxndr

1
@alxndr, bu nedenle dosya sistemlerinizi ayrı tutmak iyi bir fikirdir - bu şekilde, /tmpdiğer dosya sistemlerinizi etkilemez.
paxdiablo

Cevabınız "sistem silinmişse yeniden başlattıktan sonra dosyayı kullanmayacak" için son derece uygundur. Ancak şu soru soruldu: "inode işaretçisi silindikten sonra inode nasıl geri alınır veya yeniden kullanılır?". Temel olarak linux çekirdeği, oluşturulduğunda dosyaya yeni bir inode oluşturur ve ayrıca bir dosyayı sildiğinizde inode'yu otomatik olarak geri almaz.
Mohanraj

1
@AshishKarpe, OP'nin üretim sunucularından bahsetmediği için kendi durumunuz hakkında konuştuğunuzu varsayıyorum . Eğer derhal yeniden başlatamazsanız, iki olasılık vardır. Birincisi, uçuştaki işlemlerin sonunda disk kaynaklarının serbest bırakılabilmesi için mevcut dosyaları kapatmasını umuyoruz. İkincisi, üretim sunucuları bile bir noktada yeniden önyükleme için bir kapsama sahip olmalıdır - sadece planlanan bir kesinti zamanlayın veya bir sonraki kesinti penceresinin gelmesini bekleyin.
paxdiablo

2
Sanırım ls -Abunun yerine istiyorsun ls -a. Neden saymak istiyorsun? ve ..?
jarno

205

Çok şanssızsanız, tüm düğümlerin yaklaşık% 100'ünü kullandınız ve scipt oluşturamazsınız. Bunu ile kontrol edebilirsiniz df -ih.

O zaman bu bash komutu size yardımcı olabilir:

sudo find . -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -n

Ve evet, bu zaman alacaktır, ancak dizini en fazla dosyayla bulabilirsiniz.


8
hile yapar. benim sorunum / lib / php / sessions dizininde inanılmaz sayıda oturum olmasıydı. belki birileri aynı sorunu
yaşıyor

2
Birisi bu bul, kes, uniq türünü tek bir awk komutuna yeniden yazmalıdır!
mogsie

5
@alxndr awkdizinin bir karmasını ve dosya sayısını bir benzileme satırı ayırmadan ve sıralamaksızın tutabilir. Bununla birlikte, belki de bir gelişme: find . -maxdepth 1 -type d | grep -v '^\.$' | xargs -n 1 -i{} find {} -xdev -type f | cut -d "/" -f 2 | uniq -c | sort -n- bu sadece son listeyi sıralar.
mogsie

12
Herhangi bir dosya oluşturamazsanız, bu bile başarısızsort olabilir , çünkü her şeyi hafızada tutamayabilir ve otomatik olarak geçici bir dosya yazmaya geri dönmeye çalışacaktır. Açıkça başarısız olacak bir süreç ...
Mikko Rantalainen

10
sortbenim için başarısız oldu, ama --buffer-size=10Ghangisinin işe yaradığını verebildim .
Frederick Nord

69

Benim durumum, inode dışında olduğum ve yapabileceğim her şeyi silmiştim.

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/sda1      942080 507361     11  100% /

Ben bir ubuntu 12.04LTS üzerinde ve eksik paketi nedeniyle apt kırık çünkü yaklaşık 400.000 inode aldı eski linux çekirdekleri kaldıramadı. Ve yeni paketi yükleyemedim çünkü inode dışındaydım, bu yüzden takıldım.

Yaklaşık 10.000 inode boşaltmak için birkaç eski linux çekirdeğini el ile sildim

$ sudo rm -rf /usr/src/linux-headers-3.2.0-2*

Bu, eksik paketi yüklememe ve uygunluğumu düzeltmeme izin vermek için yeterliydi

$ sudo apt-get install linux-headers-3.2.0-76-generic-pae

ve sonra eski linux çekirdeklerinin geri kalanını uygun şekilde çıkarın

$ sudo apt-get autoremove

şimdi işler çok daha iyi

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/sda1      942080 507361 434719   54% /

3
Benzer bir durumda kendi yaklaşımıma en yakın olan buydu. Daha temkinli bir yaklaşımın help.ubuntu.com/community/Lubuntu/Documentation/…
beldaz

Benim durumum tam olarak! Ama ilerlemek için "sudo apt-get autoremove -f" kullanmak zorunda kaldı
Tony Sepia

Bunu yapmak güvenli mi: sudo rm -rf /usr/src/linux-headers-3.2.0-2*Eğer o çekirdeği kullanmadığımdan emin miyim?
Mars Lee

@MarsLee Şu anda "uname -a" ile hangi çekirdeğin çalıştığını kontrol edebilirsiniz
Dominique Eav

$ sudo apt-get autoremoveYalnız aramak , hileyi benim için yaptı.
Morten Grum

49

Çözümüm:

Bunun bir inode problemi olup olmadığını bulmaya çalışın:

df -ih

Büyük düğüm sayısı olan kök klasörleri bulmaya çalışın:

for i in /*; do echo $i; find $i |wc -l; done

Belirli klasörleri bulmaya çalışın:

for i in /src/*; do echo $i; find $i |wc -l; done

Bu linux başlıklarıysa, en eski olanları kaldırmayı deneyin:

sudo apt-get autoremove linux-headers-3.13.0-24

Şahsen onları bağlı bir klasöre taşıdım (çünkü benim için son komut başarısız oldu) ve en son yüklü:

sudo apt-get autoremove -f

Bu benim sorunumu çözdü.


1
Benim durumumda oldu SpamAssasin-Temp. find /var/spool/MailScanner/incoming/SpamAssassin-Temp -mtime +1 -print | xargs rm -fişi yaptı :) Teşekkürler!
joystick

4
Benim için bu saatler sürüyordu. Ancak, basit bir çözüm var: İkinci komut belirli bir dizine asıldığında, geçerli komutu öldürün ve / * 'yı asılı olduğu dizine değiştirmeye yeniden başlayın. Ben suçlu <dakikasına kadar detaya inebildim.
Michael Terry

Aynı satırdaki sayıları yazdırmak için komutunuzun bu varyantını kullandım: for i in /usr/src/*; do echo -en "$i\t"; find $i 2>/dev/null |wc -l; done
cscracker

for i in /src/*; do echo "$i, `find $i |wc -l`"; done|sort -nrk 2|head -10En büyük 10 dizini göster
Mark Simon

12

Ben aynı sorun vardı, php dizin oturumlarını kaldırarak düzeltildi

rm -rf /var/lib/php/sessions/

/var/lib/php5Eski bir php sürümü kullanıyorsanız altında olabilir .

Aşağıdaki izinle yeniden oluşturun

mkdir /var/lib/php/sessions/ && chmod 1733 /var/lib/php/sessions/

Debian'daki dizin için varsayılan olarak izin gösterildi drwx-wx-wt(1733)


1
Neden olduğuna dair fikri olan?
Sibidharan

1
@Sibidharan benim durumumda eski PHP oturumlarını temizlemek için PHP cron işi çalışmadığı için oldu.
sert

3
rm -rf /var/lib/php/sessions/*muhtemelen daha iyi bir komut olurdu - oturum dizinini kaldırmayacak, sadece içeriği ... Sonra yeniden yaratma konusunda endişelenmenize gerek yok
Shadow

Ben php oturumu yoktu ama buna benzer magento oturum sorunu. Yön için teşekkürler.
Mohit

php oturumları cron işleri ile temizlenmemeli, php.ini içinde session.gc_maxlifetime ayarlanmalıdır php.net/manual/en/…

2

Bunu, bir spam saldırısının ardından bir HostGator hesabında (tüm barındırmalarına inode sınırları koyan) yaşadık. /Root/.cpanel/comet içinde çok sayıda kuyruk kaydı bıraktı. Bu gerçekleşirse ve ücretsiz inode'unuz yoksa, bu cpanel yardımcı programını kabuk üzerinden çalıştırabilirsiniz:

/usr/local/cpanel/bin/purge_dead_comet_files

2

Çok sayıda dosyayı silmek için RSYNC'yi kullanabilirsiniz

rsync -a --delete blanktest/ test/

İçinde 0 dosya bulunan blanktest klasörü oluşturun ve komut, test klasörlerinizi çok sayıda dosyayla senkronize edecektir (Bu yöntemi kullanarak yaklaşık 5 milyon dosyayı sildim).

Sayesinde http://www.slashroot.in/which-is-the-fastest-method-to-delete-files-in-linux


Makale / yorumlardan söyleyebileceğimden, bu, rm *joker karakteri genişletme ve her argümanı geçirme / işleme nedeniyle çok sayıda dosyadan daha hızlıdır , ancak çok sayıda dosya içeren rm test/bir test/klasörü silmek için iyidir .
mwfearnley

Uyarı, bu iyi çalışıyor, ancak izinleri boş dizinde doğru ayarladığınızdan emin olun! Bunu yapmadım ve yanlışlıkla PHP oturumları dizinimdeki izinleri değiştirdim. Neyi berbat ettiğimi anlamak iki saat sürdü.
aecend

1

eaccelerator PHP bloklara derler çünkü soruna neden olabilir ... Ben ağır yük bir sitede bir Amazon AWS sunucusu ile bu sorunu yaşadım. Sorun yaşamaya devam ederseniz / var / cache / eaccelerator içindeki eaccelerator önbelleğini silerek Inodes'u boşaltın.

rm -rf /var/cache/eaccelerator/*

(veya önbellek yönünüz ne olursa olsun)


1

Son zamanlarda benzer bir sorunla karşılaştık, Bir işlemin silinen bir dosyaya başvurması durumunda, Inode serbest bırakılmayacaktır, bu yüzden lsof / öğesini kontrol etmeniz ve işlemi öldürmeniz / yeniden başlatmanız inode'ları serbest bırakacaktır.

Burada yanılıyorsam düzelt.


1

Daha önce de belirtildiği gibi, çok sayıda küçük dosya varsa, dosya sistemi inode bitebilir. Burada çoğu dosya içeren dizinleri bulmak için bazı araçlar sağladım .


0

Geç cevap: Benim durumumda, oturum dosyalarımın altındaydı

/var/lib/php/sessions

Inodes kullanıyorlardı.
Hatta silme işlemini tetiklemek için crontab'ımı açamadım veya yeni bir dizin yapamadım. PHP kullandığımdan beri , örnek 1'deki kodu kopyaladığım ve kodun bu bölümünü yürütmek için bir cronjob ayarladığım bu kılavuzumuz var .

<?php
// Note: This script should be executed by the same user of web server 
process.

// Need active session to initialize session data storage access.
session_start();

// Executes GC immediately
session_gc();

// Clean up session ID created by session_gc()
session_destroy();
?>

Eğer crontab'ımı nasıl açabileceğimi merak ediyorsanız, o zaman bazı oturumları CLI aracılığıyla manuel olarak sildim.

Bu yardımcı olur umarım!


0

bu bilgiyi görebiliyordun

for i in /var/run/*;do echo -n "$i "; find $i| wc -l;done | column -t

-2

Bu soruya şimdiye kadar birçok yanıt geldi ve yukarıdakilerin hepsi somut görünüyor. Ben statgiderken kullanarak güvenli olacağını düşünüyorum , ama OS bağlı olarak, bazı inode hataları size sürünen alabilirsiniz. Bu nedenle, herhangi bir taşma sorununu önlemek için kendi statarama işlevinizi uygulamak 64bitoldukça uyumlu görünmektedir.


burada örnekleri çok seviyoruz;)
Bohne

-3

Bağlantı istasyonu kullanıyorsanız, tüm görüntüleri kaldırın. Birçok yer kullandılar ....

Tüm kapsayıcıları durdur

docker stop $(docker ps -a -q)

Tüm kapsayıcıları sil

docker rm $(docker ps -a -q)

Tüm resimleri sil

docker rmi $(docker images -q)

Bana çalışıyor


Bu, sorunun "çok fazla inode" olup olmadığını saptamaya yardımcı olmaz.
Mark Stosberg

Bunun Docker ile bir ilgisi yok.
Urda
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.