Знайдіть, де використовуються вузли


189

Тому я отримав попередження від нашої системи моніторингу на одному з наших вікон, що кількість вільних вводів у файловій системі зменшується.

df -i вихід показує це:

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

Як бачимо, кореневий розділ використовує 81% своїх входів.
Я підозрюю, що всі вони використовуються в одному каталозі. Але як я можу знайти, де це?

Відповіді:


214

Я бачив це запитання на стаковому потоці, але відповіді мені не сподобався, і це справді питання, яке повинно бути тут на U&L.

В основному для кожного файлу файлової системи використовується inode. Таким чином, вичерпання вкладів зазвичай означає, що у вас багато малих файлів. Тож справді виникає питання, "який каталог містить велику кількість файлів у ньому?"

У цьому випадку файлова система, про яку ми піклуємося, є кореневою файловою системою /, тому ми можемо використовувати таку команду:

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

Це скине список кожного каталогу файлової системи з префіксом із кількістю файлів (та підкаталогів) у цьому каталозі. Таким чином, каталог з найбільшою кількістю файлів буде внизу.

У моєму випадку це виявляється наступним:

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

Таким чином, в основному /var/spool/postfix/maildropспоживають усі нутрощі.

Зауважте, у цій відповіді є три застереження, які я можу придумати. Він не може правильно обробляти нові рядки на шляху. Я знаю , що моя файлова не має файлів з символами нового рядка, і так як це використовується тільки для споживання людиною, потенційна проблема не варто вирішувати (і завжди можна замінити \nз \0і використовувати sort -zвище). Він також не обробляє, якщо файли розкинуті серед великої кількості каталогів. Це, мабуть, мало, тому я вважаю ризик прийнятним. Він також буде рахувати жорсткі посилання на один і той же файл (тому використовуючи лише один inode) кілька разів. Знову ж, навряд чи дасть помилкові позитиви


Основна причина, що мені не сподобалася відповідь на відповідь stackoverflow - це те, що всі вони перетинають межі файлової системи. Оскільки моя проблема була в кореневій файловій системі, це означає, що вона пройде через кожну змонтовану файлову систему. Накидання -xdevкоманд знаходження навіть не спрацювало належним чином.
Наприклад, найбільш схвалена відповідь:

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

Якщо ми змінимо це замість на

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

незважаючи на те /mnt/foo, що це кріплення, він також є каталогом кореневої файлової системи, тому він з'явиться find . -mount -type d, і тоді він буде переданий до пункту ls -a $i, який зануриться в кріплення.

Натомість findу моїй відповіді перерахований каталог кожного окремого файлу на кріпленні. Отже, в основному зі структурою файлів, наприклад:

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

ми закінчуємо

/foo
/foo
/pop

Тож нам просто треба порахувати кількість повторюваних рядків.


2
@MohsenPahlevanzadeh, що не є частиною моєї відповіді, я коментував, чому мені не подобається рішення, оскільки це звичайна відповідь на це питання.
Патрік

7
Використання прив’язки для прив’язки є більш надійним способом уникнути пошуку інших файлових систем, оскільки дозволяє отримати доступ до файлів під точками монтування. Наприклад, уявіть, що я створюю 300 000 файлів під, /tmpа потім система налаштована для монтажу tmpfs /tmp. Тоді ви не зможете знайти файли findсамостійно. Навряд чи сенаріо, але варто зазначити.
Graeme

2
Обидві роботи просто повинні були видалити сортування, тому що сортування потребує створення файлу, коли вихід достатньо великий, що було неможливо, оскільки я потрапив на 100% використання inodes.
qwertzguy

1
Зауважте, що, -printfздається, це розширення GNU, оскільки версія BSD, доступна в OS X, не підтримує його.
Xiong Chiamiov

1
Припущення, що всі файли є в одному каталозі, є складним. Багато програм знають, що багато файлів у одному каталозі мають погану продуктивність і, таким чином,
хешують

26

Про це повідомлено звідси за запитом запитувача:

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

І якщо ви хочете залишитися в тій же файловій системі, ви зробите:

du --inodes -xS

Ось кілька прикладів виводу:

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

ЗАРАЗ З LS:

Кілька людей згадували, що не мають оновлених базових програм, а параметр --inodes їм недоступний. Отже, ось лс:

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

Якщо вам цікаво, душа і душа цього втомлювального шматочка regexє заміною filenameв кожному з ls'sрекурсивних результатів пошуку на ім’я каталогу, в якому воно було знайдено. Звідси справа лише у видаленні повторних чисел inode, а потім підрахунку повторених імен каталогів та сортування відповідно.

Цей -Uваріант особливо корисний для сортування, оскільки він конкретно не сортує, а натомість подає список каталогів у оригінальному порядку - або, іншими словами, за inodeкількістю.

І звичайно, -1це неймовірно корисно тим, що вона забезпечує єдиний результат за рядком, незалежно від можливих включень нових рядків у назви файлів або інших надзвичайно нещасних проблем, які можуть виникнути при спробі розбору списку.

І звичайно -Aдля всіх, і -iдля inode, і -Rдля рекурсивних, і це довго і коротко.

Основним методом цього є те, що я замінюю кожну з імен файлів ls на її ім'я, що містить каталог у sed. Слідом за цим ... Ну, я трохи собі нечіткий. Я впевнений, що це точно підраховує файли, як ви бачите тут:

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

Це дає мені майже однакові результати duкоманди:

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:

Я думаю, що includeріч просто залежить від того, в якому каталозі програма виглядає спочатку - тому що вони однакові файли та жорстке посилання. Ніби як річ вище. Я можу помилитися з цього приводу - і я вітаю виправлення ...

DU DEMO

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

Складіть тестовий каталог:

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

Деякі довідники для дітей:

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

Створіть кілька файлів:

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

Деякі тверді посилання:

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

Подивіться на жорсткі посилання:

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

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

Вони рахуються поодинці, але перейдіть по одному каталогу вгору ...

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

Потім я запустив свій запущений сценарій знизу і:

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

І Graeme:

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

Тому я думаю, що це свідчить про те, що єдиний спосіб підрахунку inode - це inode. І тому що підрахунок файлів означає підрахунок узорів, ви не можете подвоїти підрахунок удвічі - для точного підрахунку файлів входи неможливо перерахувати більше одного разу.


2
яка версія додана --inodes? які "варіанти" / "аромати" / "posix-wannabes" / "реалізації" / що б там не було?
n611x007

Ubuntu 14.04.5: ді: невизнана опція '--inodes'
Putnik

du (GNU coreutils) 8.23 ​​від 2014 року є (це в моїй застарілій Debian Jessie). Debian> Ubuntu вибачте за цей каламбур: P Ubuntu має такі старі пакунки ...
Daniel W.

6

Я використав цю відповідь із запитань SO&W під назвою: Де використовуються всі мої введення? коли наш NAS закінчився близько 2 років тому:

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

Приклад

$ 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

Перевірка Inodes пристроїв

Залежно від вашого NAS, він може не пропонувати повнофункціональну dfкоманду. Тож у цих випадках можна скористатися tune2fsзамість цього:

$ 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

Перетинання меж файлової системи

Ви можете використовувати -xdevперемикач, щоб направити його, findщоб звузити його пошук лише на пристрої, на якому ви починаєте пошук.

Приклад

Скажіть, у мене є /homeкаталог автоматичного управління за допомогою NFS акцій від мого NAS, ім'я якого - мульдер.

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

Зауважте, що точка монтажу все ще вважається локальною для системи.

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

Тепер, коли я ініціюю find:

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

Він знайшов, /homeале жоден із автоматизованих вмістів, оскільки вони знаходяться на іншому пристрої!

Типи файлових систем

Ви можете використовувати перемикач на find, -fstypeщоб керувати типом файлових систем find.

   -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.

Приклад

Яка файлова система у мене є?

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

Таким чином, ви можете використовувати це для управління переправою:

тільки 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

тільки 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

Яким було б ваше рішення, щоб не допустити перетину меж файлової системи? Начебто, якщо /є повна, і у вас встановлені мережеві файлові системи, ви не хочете занурюватися в мережеві файлові системи.
Патрік

@Patrick - бачити оновлення, ви можете контролювати його з допомогою -fstypeдо find.
slm

1
@Gilles - проста відповідь ... не внизу все на сторінці людини знайти 8-)
slm

@Gilles - сторінка man, схоже, не вказує на те, що -xtypeвиключає файлові системи, вона виглядає як тип файлу. Я знаходжу лише такі приклади:find . \( -fstype nfs -prune \)
slm

@Gilles - Я звертався до Патріка Q у коментарях про те, як уберегтися findвід перетину меж файлової системи. У його колишній. він згадує: "Як, якщо / є те, що повно, і у вас встановлені мережеві файлові системи, ви не хочете занурюватися в мережеві файлові системи".
slm


3

Щоб перелічити детальне використання inode для /, скористайтеся такою командою:

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" 

Ласкаво просимо сюди! Я пропоную наступного разу форматувати краще, будь ласка.
peterh

1
Це однолінійка, я не бачу нічого поганого в цьому.
sjas

2

Однозначно відповідь з максимальним обновленням допомагає зрозуміти поняття inode в linux та unix, однак це не дуже допомагає, коли мова йде про актуальну проблему видалення або видалення вкладень з диска. Найпростіший спосіб зробити це в системах на базі ubuntu - видалити небажані заголовки та зображення ядра Linux.

sudo apt-get autoremove

Зробив би це за вас. У моєму випадку використання дози склало 78%, через що я отримав попередження.

$ 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

Після запуску sudo apt-get autoremoveкоманди він знизився до 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

Це лише моє спостереження, яке врятувало мій час. Люди можуть знайти щось краще рішення, ніж це.


2

Мені здається, що швидше і простіше деталізувати за допомогою наступної команди:

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

170202  var
157325  opt
103134  usr
53383   tmp
<snip>

Потім ви можете зайти, varнаприклад, і подивитися, який великий Inode за допомогою каталогів знаходиться там.


0

Кожна відповідь на даний момент передбачає, що проблема полягає в тому, що багато файлів в одному каталозі, а не багато підкаталогів, що сприяють проблемі. На щастя, рішення - просто використовувати менше прапорів.

# 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

Або з укороченими варіантами: du --inodes -x | sort -n. На жаль, не всі версії duмають параметр inodes.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.