Найдите, где используются inode

189

Поэтому я получил предупреждение от нашей системы мониторинга на одном из наших блоков о том, что число свободных инодов в файловой системе уменьшается.

df -i вывод показывает это:

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

Как видите, в корневом разделе 81% используемых инодов.
Я подозреваю, что все они используются в одном каталоге. Но как я могу найти, где это?

Патрик
источник

Ответы:

214

Я видел этот вопрос в stackoverflow, но мне не понравился ни один из ответов, и это действительно вопрос, который должен быть здесь, на 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потребляет все inode.

Обратите внимание, у этого ответа есть три предостережения, о которых я могу подумать. Он неправильно обрабатывает что-либо с символами новой строки в пути. Я знаю , что моя файловая не имеет файлов с символами новой строки, и так как это используется только для потребления человеком, потенциальная проблема не стоит решать (и всегда можно заменить \nс \0и использовать sort -zвыше). Это также не обрабатывает, если файлы распределены среди большого количества каталогов. Хотя это маловероятно, поэтому я считаю риск приемлемым. Он также будет подсчитывать жесткие ссылки на один и тот же файл (таким образом, используя только один индекс) несколько раз. Опять же, вряд ли дать ложные срабатывания


Основная причина, по которой мне не понравился ни один из ответов на ответ 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
Использование bind mount - более надежный способ избежать поиска в других файловых системах, поскольку он позволяет получить доступ к файлам в точках монтирования. Например, представьте, что я создаю 300 000 файлов, /tmpа затем система настроена на монтирование tmpfs /tmp. Тогда вы не сможете найти файлы в findодиночку. Вряд ли сенарио, но стоит отметить.
Грэм
2
Обе работы просто должны были удалить сортировку, потому что сортировка должна создавать файл, когда выходные данные достаточно велики, что было невозможно, так как я достиг 100% использования inode.
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

ТЕПЕРЬ С ЛС:

Несколько человек упомянули, что у них нет современных coreutils, и опция --inodes для них недоступна. Итак, вот ls:

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результатов рекурсивного поиска имя каталога, в котором он был найден. Оттуда это просто вопрос сжатия повторяющихся номеров инодов, затем подсчета повторяющихся имен каталогов и соответствующей сортировки.

Эта -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

И Грэм:

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

Так что я думаю, что это показывает, что единственный способ подсчитать inode - это inode. А поскольку подсчет файлов означает подсчет инодов, вы не можете вдвойне подсчитывать иноды - для точного подсчета файлов иноды не могут быть подсчитаны более одного раза.

mikeserv
источник
2
какая версия добавлена --inodes? какие "варианты" / "вкусы" / "posix-wannabes" / "реализации" / что бы это ни было?
n611x007
Ubuntu 14.04.5: du: нераспознанная опция '--inodes'
Путник
В du (GNU coreutils) 8.23 ​​из 2014 года он есть (он в моей устаревшей Debian Jessie). Debian> Ubuntu извините за этот каламбур: P В Ubuntu есть такие старые пакеты ...
Даниэль У.
6

Я использовал этот ответ от SO Q & A под названием: Где используются все мои иноды? когда наш 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

Проверка Inode устройства

В зависимости от вашего 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, чье имя - mulder.

$ 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

только нфс

$ 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
источник
Каким было бы ваше решение, чтобы предотвратить пересечение границ файловой системы? Например, если /все заполнено, и у вас смонтированы сетевые файловые системы, вы не хотите погружаться в сетевые файловые системы.
Патрик
@Patrick - видеть обновления, вы можете контролировать его с помощью -fstypeк find.
SLM
1
@ Жиль - простой ответ ... не пролистал весь путь в справочной странице find 8-)
slm
@Gilles - справочная страница, кажется, не указывает, что -xtypeисключает файловые системы, она смотрит на тип файла. Я нахожу только примеры, подобные этому:find . \( -fstype nfs -prune \)
slm
@ Жиль - я обращался к вопроснику Патрика в комментариях о том, как избежать findпересечения границ файловой системы. В его бывшем. он упоминает «Как если / заполнено, а у вас смонтированы сетевые файловые системы, вы не хотите углубляться в сетевые файловые системы».
SLM
4

Команда для поиска используемого инода:

for i in /*; do echo $i; find $i |wc -l | sort ; done
Ашиш Карпе
источник
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" 
user108434
источник
Добро пожаловать! Предлагаю в следующий раз форматировать лучше, пожалуйста.
user259412
1
Это единственное, что я не вижу в этом ничего плохого.
Sjas
2

Определенно ответ с максимальным числом голосов помогает понять концепцию inode в linux и unix, однако это не очень помогает, когда речь идет о реальной проблеме удаления или удаления inode с диска. Более простой способ сделать это в системах на основе Ubuntu - удалить ненужные заголовки и образы ядра Linux.

sudo apt-get autoremove

Сделал бы это для вас. В моем случае использование inode было 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и посмотреть, что там за большой каталог, использующий каталоги.

JonoB
источник
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.

OrangeDog
источник