Temukan di mana inode sedang digunakan

189

Jadi saya menerima peringatan dari sistem pemantauan kami di salah satu kotak kami bahwa jumlah inode gratis pada sistem file semakin rendah.

df -i output menunjukkan ini:

Filesystem       Inodes  IUsed    IFree IUse% Mounted on
/dev/xvda1       524288 422613   101675   81% /

Seperti yang Anda lihat, partisi root menggunakan 81% dari inode yang digunakan.
Saya curiga mereka semua digunakan dalam satu direktori. Tetapi bagaimana saya bisa menemukan di mana itu?

Patrick
sumber

Jawaban:

214

Saya melihat pertanyaan ini di atas stackoverflow, tetapi saya tidak menyukai jawaban apa pun, dan itu sebenarnya adalah pertanyaan yang seharusnya ada di sini di U&L.

Pada dasarnya inode digunakan untuk setiap file pada sistem file. Jadi kehabisan inode umumnya berarti Anda punya banyak file kecil yang bertebaran. Jadi pertanyaannya adalah, "direktori apa yang memiliki banyak file di dalamnya?"

Dalam hal ini, sistem file yang kita pedulikan adalah sistem file root /, sehingga kita dapat menggunakan perintah berikut:

find / -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n

Ini akan membuang daftar setiap direktori pada sistem file yang diawali dengan jumlah file (dan subdirektori) di direktori tersebut. Dengan demikian direktori dengan jumlah file terbesar akan berada di bagian bawah.

Dalam kasus saya, ini akan muncul sebagai berikut:

   1202 /usr/share/man/man1
   2714 /usr/share/man/man3
   2826 /var/lib/dpkg/info
 306588 /var/spool/postfix/maildrop

Jadi pada dasarnya /var/spool/postfix/maildropadalah mengkonsumsi semua inode.

Perhatikan, jawaban ini memang memiliki tiga peringatan yang dapat saya pikirkan. Itu tidak benar menangani apa pun dengan baris baru di jalan. Saya tahu sistem file saya tidak memiliki file dengan baris baru, dan karena ini hanya digunakan untuk konsumsi manusia, masalah potensial tidak layak untuk diselesaikan (dan seseorang selalu dapat mengganti \ndengan \0dan menggunakan di sort -zatas). Itu juga tidak menangani jika file tersebar di antara sejumlah besar direktori. Ini tidak mungkin, jadi saya menganggap risikonya dapat diterima. Ini juga akan menghitung tautan keras ke file yang sama (sehingga hanya menggunakan satu inode) beberapa kali. Sekali lagi, tidak mungkin memberikan positif palsu


Alasan utama saya tidak suka salah satu jawaban pada jawaban stackoverflow adalah mereka semua melewati batas filesystem. Karena masalah saya adalah pada sistem berkas root, ini berarti ia akan melintasi setiap sistem file yang dipasang. Melemparkan -xdevperintah find bahkan tidak akan berfungsi dengan baik.
Misalnya, jawaban yang paling banyak dipilih adalah yang ini:

for i in `find . -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n

Jika kita mengubahnya menjadi

for i in `find . -xdev -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n

meskipun /mnt/fooadalah mount, itu juga merupakan direktori pada sistem file root, jadi itu akan muncul find . -mount -type d, dan kemudian akan diteruskan ke ls -a $i, yang akan menyelam ke mount.

The findin my answer gantinya daftar direktori setiap file tunggal di mount. Jadi pada dasarnya dengan struktur file seperti:

/foo/bar
/foo/baz
/pop/tart

kita berakhir dengan

/foo
/foo
/pop

Jadi kita hanya perlu menghitung jumlah baris duplikat.

Patrick
sumber
2
@MohsenPahlevanzadeh yang bukan bagian dari jawaban saya, saya berkomentar mengapa saya tidak suka solusinya karena ini adalah jawaban umum untuk pertanyaan ini.
Patrick
7
Menggunakan bind mount adalah cara yang lebih kuat untuk menghindari pencarian sistem file lain karena memungkinkan akses ke file di bawah mount point. Misalnya, bayangkan saya membuat 300.000 file di bawah /tmpdan kemudian sistem dikonfigurasi untuk me-mount tmpfs /tmp. Maka Anda tidak akan dapat menemukan file dengan findsendirian. Senario yang tidak mungkin, tetapi patut dicatat.
Graeme
2
Kedua pekerjaan hanya harus menghapus sort karena sort perlu membuat file ketika outputnya cukup besar, yang tidak mungkin karena saya menekan 100% penggunaan inode.
qwertzguy
1
Catatan yang -printftampaknya merupakan ekstensi GNU untuk ditemukan, karena versi BSD yang tersedia di OS X tidak mendukungnya.
Xiong Chiamiov
1
Asumsi bahwa semua file dalam satu direktori adalah yang sulit. Banyak program tahu bahwa banyak file dalam satu direktori memiliki kinerja yang buruk dan dengan demikian
mem-
26

Ini diposkan ulang dari sini atas permintaan penanya:

du --inodes -S | sort -rh | sed -n \
        '1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/\1...\2/;p}'

Dan jika Anda ingin tetap di sistem file yang sama Anda lakukan:

du --inodes -xS

Berikut beberapa contoh output:

15K     /usr/share/man/man3
4.0K    /usr/lib
3.6K    /usr/bin
2.4K    /usr/share/man/man1
1.9K    /usr/share/fonts/75dpi
...
519     /usr/lib/python2.7/site-packages/bzrlib
516     /usr/include/KDE
498     /usr/include/qt/QtCore
487     /usr/lib/modules/3.13.6-2-MANJARO/build/include/config
484     /usr/src/linux-3.12.14-2-MANJARO/include/config

SEKARANG DENGAN LS:

Beberapa orang mengatakan mereka tidak memiliki coreutil terbaru dan opsi --inodes tidak tersedia untuk mereka. Jadi, ini dia:

ls ~/test -AiR1U | 
sed -rn '/^[./]/{h;n;};G;
    s|^ *([0-9][0-9]*)[^0-9][^/]*([~./].*):|\1:\2|p' | 
sort -t : -uk1.1,1n |
cut -d: -f2 | sort -V |
uniq -c |sort -rn | head -n10

Jika Anda penasaran, hati-dan-jiwa dari bagian yang membosankan regexitu menggantikan filenamesetiap ls'shasil pencarian rekursif dengan nama direktori tempat ditemukan. Dari sana itu hanya masalah memeras nomor inode berulang kemudian menghitung nama direktori berulang dan mengurutkannya.

The -Upilihan adalah sangat membantu dengan menyortir dalam hal itu secara khusus tidak tidak memilah, dan bukan menyajikan daftar direktori dalam urutan asli - atau, dengan kata lain, dengan inodenomor.

Dan tentu saja -1ini sangat membantu dalam memastikan hasil tunggal per baris, terlepas dari kemungkinan memasukkan baris baru dalam nama file atau masalah yang sangat disayangkan yang mungkin terjadi ketika Anda mencoba mengurai daftar.

Dan tentu saja -Auntuk semua dan -iuntuk inode dan -Runtuk rekursif dan itu panjang dan pendek.

Metode yang mendasari ini adalah bahwa saya mengganti setiap nama file ls dengan nama direktori yang berisi sed. Sebagai lanjutan dari itu ... Yah, aku sendiri agak kabur. Saya cukup yakin itu secara akurat menghitung file, seperti yang Anda lihat di sini:

% _ls_i ~/test
> 100 /home/mikeserv/test/realdir
>   2 /home/mikeserv/test
>   1 /home/mikeserv/test/linkdir

Ini memberikan saya hasil yang hampir sama dengan duperintah:

DU:

15K     /usr/share/man/man3
4.0K    /usr/lib
3.6K    /usr/bin
2.4K    /usr/share/man/man1
1.9K    /usr/share/fonts/75dpi
1.9K    /usr/share/fonts/100dpi
1.9K    /usr/share/doc/arch-wiki-markdown
1.6K    /usr/share/fonts/TTF
1.6K    /usr/share/dolphin-emu/sys/GameSettings
1.6K    /usr/share/doc/efl/html

LS:

14686   /usr/share/man/man3:
4322    /usr/lib:
3653    /usr/bin:
2457    /usr/share/man/man1:
1897    /usr/share/fonts/100dpi:
1897    /usr/share/fonts/75dpi:
1890    /usr/share/doc/arch-wiki-markdown:
1613    /usr/include:
1575    /usr/share/doc/efl/html:
1556    /usr/share/dolphin-emu/sys/GameSettings:

Saya pikir includemasalahnya tergantung pada direktori mana program terlihat pada awalnya - karena mereka file yang sama dan di-hardlink. Agak suka hal di atas. Saya bisa salah tentang itu - dan saya menerima koreksi ...

DU DEMO

% du --version
> du (GNU coreutils) 8.22

Buat direktori pengujian:

% mkdir ~/test ; cd ~/test
% du --inodes -S
> 1       .

Beberapa direktori anak-anak:

% mkdir ./realdir ./linkdir
% du --inodes -S
> 1       ./realdir
> 1       ./linkdir
> 1       .

Buat beberapa file:

% printf 'touch ./realdir/file%s\n' `seq 1 100` | . /dev/stdin
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

Beberapa hardlink:

% printf 'n="%s" ; ln ./realdir/file$n ./linkdir/link$n\n' `seq 1 100` | 
    . /dev/stdin
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

Lihatlah hardlinks:

% cd ./linkdir
% du --inodes -S
> 101

% cd ../realdir
% du --inodes -S
> 101

Mereka dihitung sendiri, tetapi naik satu direktori ...

% cd ..
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

Kemudian saya menjalankan skrip saya dari bawah dan:

> 100     /home/mikeserv/test/realdir
> 100     /home/mikeserv/test/linkdir
> 2       /home/mikeserv/test

Dan Graeme:

> 101 ./realdir
> 101 ./linkdir
> 3 ./

Jadi saya pikir ini menunjukkan bahwa satu-satunya cara untuk menghitung inode adalah dengan inode. Dan karena menghitung file berarti menghitung inode, Anda tidak dapat menghitung dua kali inode - untuk menghitung file secara akurat inode tidak dapat dihitung lebih dari sekali.

mikeserv
sumber
2
versi mana yang ditambahkan --inodes? yang "varian" / "rasa" / "posix-wannabes" / "implementasi" / apa pun yang memilikinya?
n611x007
Ubuntu 14.04.5: du: opsi tidak dikenal '--inodes'
Putnik
du (GNU coreutils) 8.23 ​​dari 2014 memilikinya (sudah ada dalam Debian Jessie saya yang sudah usang). Debian> Ubuntu maaf untuk permainan kata itu: P Ubuntu memiliki paket yang sangat lama ...
Daniel W.
6

Saya menggunakan jawaban ini dari SO T&J berjudul: Di mana semua inode saya digunakan? ketika NAS kami habis sekitar 2 tahun yang lalu:

$ find . -type d -print0 \
    | while IFS= read -rd '' i; do echo $(ls -a "$i" | wc -l) "$i"; done \
    | sort -n

Contoh

$ find . -type d -print0 \
    | while IFS= read -rd '' i; do echo $(ls -a "$i" | wc -l) "$i"; done \
    | sort -n
...
110 ./MISC/nodejs/node-v0.8.12/out/Release/obj.target/v8_base/deps/v8/src
120 ./MISC/nodejs/node-v0.8.12/doc/api
123 ./apps_archive/monitoring/nagios/nagios-check_sip-1.3/usr/lib64/nagios
208 ./MISC/nodejs/node-v0.8.12/deps/openssl/openssl/doc/crypto
328 ./MISC/nodejs/node-v0.8.12/deps/v8/src
453 ./MISC/nodejs/node-v0.8.12/test/simple

Memeriksa inode perangkat

Tergantung pada NAS Anda, itu mungkin tidak menawarkan dfperintah berfitur lengkap . Jadi dalam kasus ini Anda dapat menggunakan tune2fssebagai gantinya:

$ sudo tune2fs -l /dev/sda1 |grep -i inode
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super huge_file uninit_bg dir_nlink extra_isize
Inode count:              128016
Free inodes:              127696
Inodes per group:         2032
Inode blocks per group:   254
First inode:              11
Inode size:           128
Journal inode:            8
Journal backup:           inode blocks

Melintasi batas sistem file

Anda dapat menggunakan -xdevsakelar untuk mengarahkan findmempersempit pencariannya hanya ke perangkat tempat Anda memulai pencarian.

Contoh

Katakanlah saya memiliki /homedirektori saya yang diotomatisasi melalui saham NFS dari NAS saya, yang namanya mulder.

$ df -h /home/sam 
Filesystem            Size  Used Avail Use% Mounted on
mulder:/export/raid1/home/sam
                      917G  572G  299G  66% /home/sam

Perhatikan bahwa titik pemasangan masih dianggap lokal ke sistem.

$ df -h /home/ .
Filesystem            Size  Used Avail Use% Mounted on
-                        0     0     0   -  /home
/dev/mapper/VolGroup00-LogVol00
                      222G  159G   52G  76% /

Sekarang ketika saya memulai find:

$ find / -xdev  | grep '^/home'
/home

Ia menemukan /hometetapi tidak ada konten yang diautomatiskan karena mereka berada di perangkat yang berbeda!

Jenis sistem file

Anda dapat menggunakan switch to find, -fstypeuntuk mengontrol tipe sistem file yang findakan ditinjau.

   -fstype type
          File is on a filesystem of type type.  The valid filesystem types 
          vary among different versions of Unix; an incomplete list of 
          filesystem  types that are accepted on some version of Unix or 
          another is: ufs, 4.2, 4.3, nfs, tmp, mfs, S51K, S52K.  You can use 
          -printf with the %F directive to see the types of your
          filesystems.

Contoh

Sistem file apa yang saya miliki?

$ find . -printf "%F\n" | sort -u
ext3

Jadi Anda bisa menggunakan ini untuk mengontrol persimpangan:

hanya ext3

$ find . -fstype ext3 | head -5
.
./gdcm
./gdcm/gdcm-2.0.16
./gdcm/gdcm-2.0.16/Wrapping
./gdcm/gdcm-2.0.16/Wrapping/CMakeLists.txt

hanya nfs

$ find . -fstype nfs | head -5
$ 

ext3 & ext4

$ find . -fstype ext3 -o -fstype ext4 | head -5
.
./gdcm
./gdcm/gdcm-2.0.16
./gdcm/gdcm-2.0.16/Wrapping
./gdcm/gdcm-2.0.16/Wrapping/CMakeLists.txt
slm
sumber
Apa yang akan menjadi solusi Anda untuk mencegahnya melintasi batas filesystem? Seperti jika /penuh, dan Anda memiliki sistem file jaringan yang terpasang, Anda tidak ingin masuk ke sistem file jaringan.
Patrick
@Patrick - lihat update, Anda dapat mengendalikannya menggunakan -fstypeuntuk find.
slm
1
@Gilles - jawaban sederhana ... tidak membuka halaman sepenuhnya di halaman manual find 8-)
slm
@Gilles - halaman manual tampaknya tidak menunjukkan bahwa -xtypetidak termasuk sistem file, sepertinya melihat pada jenis file. Saya hanya menemukan contoh seperti ini:find . \( -fstype nfs -prune \)
slm
@Gilles - Saya menyapa Patrick's Q di komentar tentang bagaimana menjaga agar tidak findmelewati batas filesystem. Di mantannya. ia menyebutkan "Seperti jika ini penuh, dan Anda memiliki sistem berkas jaringan yang terpasang, Anda tidak ingin masuk ke sistem berkas jaringan".
slm
4

Perintah untuk menemukan inode yang digunakan:

for i in /*; do echo $i; find $i |wc -l | sort ; done
Ashish Karpe
sumber
3

Untuk membuat daftar penggunaan inode terperinci /, gunakan perintah berikut:

echo "Detailed Inode usage for: $(pwd)" ; for d in `find -maxdepth 1 -type d |cut -d\/ -f2 |grep -xv . |sort`; do c=$(find $d |wc -l) ; printf "$c\t\t- $d\n" ; done ; printf "Total: \t\t$(find $(pwd) | wc -l)\n" 
pengguna108434
sumber
Selamat datang disini! Saya sarankan, format waktu berikutnya lebih baik, tolong.
peterh
1
Ini oneliner, saya tidak melihat ada yang salah dengan itu.
sjas
2

Jawaban pasti dengan upvotes maksimum membantu memahami konsep inode di linux dan unix, tetapi itu tidak benar-benar membantu ketika datang untuk menangani masalah aktual menghapus atau menghapus inode dari disk. Cara yang lebih mudah untuk melakukan ini pada sistem berbasis ubuntu adalah menghapus header dan gambar kernel linux yang tidak diinginkan.

sudo apt-get autoremove

Akan melakukan itu untukmu. Dalam kasus saya, penggunaan inode adalah 78% karena saya menerima peringatan.

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/xvda1     524288 407957 116331   78% /
none           957443      2 957441    1% /sys/fs/cgroup
udev           956205    388 955817    1% /dev
tmpfs          957443    320 957123    1% /run
none           957443      1 957442    1% /run/lock
none           957443      1 957442    1% /run/shm
none           957443      5 957438    1% /run/user

Setelah menjalankan sudo apt-get autoremoveperintah itu turun menjadi 29%

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/xvda1     524288 150472 373816   29% /
none           957443      2 957441    1% /sys/fs/cgroup
udev           956205    388 955817    1% /dev
tmpfs          957443    320 957123    1% /run
none           957443      1 957442    1% /run/lock
none           957443      1 957442    1% /run/shm
none           957443      5 957438    1% /run/user

Ini hanya pengamatan saya yang menghemat waktu saya. Orang mungkin menemukan beberapa solusi yang lebih baik daripada ini.

Shailesh Sutar
sumber
2

Saya merasa lebih cepat dan lebih mudah untuk menelusuri menggunakan perintah berikut:

$ sudo du -s --inodes * | sort -rn

170202  var
157325  opt
103134  usr
53383   tmp
<snip>

Anda kemudian dapat masuk ke varmisalnya dan melihat apa inode besar menggunakan direktori di sana.

JonoB
sumber
0

Setiap jawaban sejauh ini mengasumsikan masalahnya adalah dengan banyak file dalam satu direktori, bukan banyak subdirektori yang berkontribusi terhadap masalah. Untungnya solusinya adalah dengan menggunakan lebih sedikit flag.

# du --inodes --one-file-system /var | sort --numeric-sort
...
2265    /var/cache/salt/minion
3818    /var/lib/dpkg/info
3910    /var/lib/dpkg
4000    /var/cache/salt/master/gitfs/refs
4489    /var/lib
5709    /var/cache/salt/master/gitfs/hash
12954   /var/cache/salt/master/gitfs
225058  /var/cache/salt/master/jobs
241678  /var/cache/salt/master
243944  /var/cache/salt
244078  /var/cache
248949  /var

Atau dengan pilihan lebih pendek: du --inodes -x | sort -n. Sayangnya tidak semua versi dumemiliki opsi inode.

OrangeDog
sumber