Найдите, где используются индексные дескрипторы

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

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

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

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

152 голоса | спросил Patrick 26 FebruaryEurope/MoscowbWed, 26 Feb 2014 21:55:50 +0400000000pmWed, 26 Feb 2014 21:55:50 +040014 2014, 21:55:50

7 ответов


181

Я просмотрел этот вопрос о потоке stackoverflow, но мне не понравился ни один из ответов, и на самом деле это вопрос, который должен быть здесь на U & L в любом случае.

В основном, для каждого файла в файловой системе используется индекс. Таким образом, исчерпывание inodes обычно означает, что у вас много маленьких файлов. Таким образом, на самом деле возникает вопрос: «В каком каталоге содержится большое количество файлов?»

В этом случае файловая система, о которой мы заботимся, это корневая файловая система /, поэтому мы можем использовать следующую команду:

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


Ключевой причиной, по которой мне не понравился какой-либо ответ в ответе stackoverflow, - все они пересекают границы файловой системы. Поскольку моя проблема была в корневой файловой системе, это означает, что она будет проходить через каждую смонтированную файловую систему. Выброс -xdev в командах find не будет работать нормально.
Например, самый последний ответ:

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 является mount, это также каталог корневой файловой системы, поэтому он появится в find . -mount -type d, а затем он будет передан в ls -a $i, который погрузится в mount.

find в моем ответе вместо этого отображает каталог каждого файла на mount. Таким образом, в основном с файловой структурой, например:

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

мы получим

/foo
/foo
/pop

Итак, нам просто нужно подсчитать количество повторяющихся строк.

ответил Patrick 26 FebruaryEurope/MoscowbWed, 26 Feb 2014 21:55:50 +0400000000pmWed, 26 Feb 2014 21:55:50 +040014 2014, 21:55:50
14

Это отправляется из здесь по просьбе афера:

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:

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

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       .

Посмотрите на hardlinks:

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

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

ответил mikeserv 4 AMpFri, 04 Apr 2014 05:21:44 +040021Friday 2014, 05:21:44
4

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

Проверка дескрипторов устройства

В зависимости от вашего 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
ответил slm 26 FebruaryEurope/MoscowbWed, 26 Feb 2014 22:20:23 +0400000000pmWed, 26 Feb 2014 22:20:23 +040014 2014, 22:20:23
2

Чтобы просмотреть подробное использование 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 29 MarpmSun, 29 Mar 2015 13:09:36 +03002015-03-29T13:09:36+03:0001 2015, 13:09:36
2

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

for i in /*; do echo $i; find $i |wc -l | sort ; done
ответил Ashish Karpe 9 WedEurope/Moscow2015-12-09T13:05:38+03:00Europe/Moscow12bEurope/MoscowWed, 09 Dec 2015 13:05:38 +0300 2015, 13:05:38
1

Я нахожу его более быстрым и простым в использовании, используя следующую команду:

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

170202  var
157325  opt
103134  usr
53383   tmp
<snip>

Затем вы можете перейти к var и посмотреть, что там находится большой индексный дескриптор, содержащий каталоги.

ответил JonoB 28 AM00000030000001631 2017, 03:47:16
0

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

sudo apt-get autoremove

Сделал бы это за вас. В моем случае использование inodes составляло 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

Это было мое наблюдение, которое спасло мое время. Люди могут найти лучшее решение, чем это.

ответил Shailesh Sutar 10 42016vEurope/Moscow11bEurope/MoscowThu, 10 Nov 2016 22:54:55 +0300 2016, 22:54:55

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132