Знайдіть каталоги з великою кількістю файлів у


33

Тож мій клієнт сьогодні отримав електронний лист від Linode про те, що їхній сервер викликав вибух служби резервного копіювання Linode. Чому? Занадто багато файлів. Я сміявся, а потім побіг:

# df -ih
Filesystem     Inodes IUsed IFree IUse% Mounted on
/dev/xvda        2.5M  2.4M   91K   97% /

Лайно. 2,4 мільйона вживаних одиниць. Що за чорт сталося ?!

Я шукав очевидних підозрюваних ( /var/{log,cache}і каталог, де розміщуються всі сайти), але не знаходжу нічого підозрілого. Десь на цьому звірі я впевнений, що існує каталог, який містить пару мільйонів файлів.

Для контексту один з моїх моїх завантажених серверів використовує 200k дескриптори і мій робочий стіл (стара установка з більш ніж 4 Тб використовуваної пам'яті) є лише трохи більше мільйона чоловік . Є проблема.

Отже, моє запитання: як я можу знайти де проблема? Чи є duдля введення ?



1
запустіть vmstat -1 100 і покажіть нам щось із цього. остерігайтеся великої кількості в CS (переключення контексту). Іноді несправна файлова система може втратити багато вправ на помилки. Або, можливо, законно, файлів багато. Це посилання має інформувати вас про файли та вставки. stackoverflow.com/questions/653096/howto-free-inode-usage може знадобитися, щоб побачити, що працює / відкрити за допомогою команди lsof.
j0h

Відповіді:


23

Перевірте, /lost+foundчи виникла проблема з диском і чимало небажаного виявлено як окремі файли, можливо, неправильно.

Перевірте, iostatчи якась програма все ще створює файли, як божевільні.

find / -xdev -type d -size +100kпідкаже, чи існує каталог, який використовує більше 100 кБ дискового простору. Це був би каталог, який містить багато файлів або містив багато файлів у минулому. Ви можете скорегувати цифру розміру.

Я не думаю, що для GNU є комбінація варіантів, щоб duвона зараховувала 1 на запис у каталозі. Ви можете зробити це, створивши список файлів findі зробивши трохи підрахунок у awk. Ось duдля inodes. Мінімально перевірений, не намагається впоратися з іменами файлів, що містять нові рядки.

#!/bin/sh
find "$@" -xdev -depth | awk '{
    depth = $0; gsub(/[^\/]/, "", depth); depth = length(depth);
    if (depth < previous_depth) {
       # A non-empty directory: its predecessor was one of its files
       total[depth] += total[previous_depth];
       print total[previous_depth] + 1, $0;
       total[previous_depth] = 0;
    }
    ++total[depth];
    previous_depth = depth;
}
END { print total[0], "total"; }'

Використання: du-inodes /. Друкує список непорожніх каталогів із загальною кількістю записів у них та їхніх підкаталогів рекурсивно. Перенаправляйте вихід на файл і переглядайте його у вільний час. sort -k1nr <root.du-inodes | headрозповість вам найбільших злочинців.


Сценарій дає помилки:awk: line 2: find: regular expression compile failed (bad class -- [], [^] or [) [^ awk: line 2: syntax error at or near ] `/tmp/tmpw99dhs': Permission denied
Radu Rădeanu

@ RaduRădeanu Ага, я бачу, я використав особливість gawk, яка не працює в інших версіях. Я додав зворотну косу рису, яку я вважаю необхідною відповідно до POSIX.
Жил "ТАК - перестань бути злим"

14

Ви можете перевірити цей сценарій:

#!/bin/bash

if [ $# -ne 1 ];then
  echo "Usage: `basename $0` DIRECTORY"
  exit 1
fi

echo "Wait a moment if you want a good top of the bushy folders..."

find "$@" -type d -print0 2>/dev/null | while IFS= read -r -d '' file; do 
    echo -e `ls -A "$file" 2>/dev/null | wc -l` "files in:\t $file"
done | sort -nr | head | awk '{print NR".", "\t", $0}'

exit 0

Це друкує 10 кращих підкаталогів за кількістю файлів. Якщо ви хочете вершину x, змініть headна head -n x, де xнатуральне число більше 0.

Для отримання 100% впевнених результатів запустіть цей скрипт з привілеями root:

папки-вершини


2019 рік: підняли 10: read: Illegal option -d... витерли -dпрапор, readсподіваючись, що нічого поганого не станеться. Повідомлять, коли він закінчить біг ...
Вільямс

3

Часто швидше, ніж знаходити, якщо ваша база пошуку застаріла:

# locate '' | sed 's|/[^/]*$|/|g' | sort | uniq -c | sort -n | tee filesperdirectory.txt | tail

Це скидає всю базу даних locate, знімає все, що минуло останнє '/' на шляху, потім сортування та "uniq -c" отримують кількість файлів / каталогів у каталозі. "Сортувати -n", накладений на хвіст, щоб отримати вам десять каталогів з найбільшою кількістю речей у них.


+1: використання бази даних locate - дуже приємна ідея!
Макс Бейкірх

Коли з будь-якої причини ви не можете скористатись функцією пошуку, запустіть find /path/to/parent -xdev > filelistспочатку, а потім направляйте sed, щоб прочитати вхід із цього списку.
Герріт

1

Ще одна пропозиція:

http://www.iasptk.com/20314-ubuntu-find-large-files-fast-from-command-line

Використовуйте ці пошуки, щоб знайти найбільші файли на вашому сервері.

Знайдіть файли понад 1 Гб

sudo find / -type f -size + 1000000k -exec ls -lh {} \;

Знайдіть файли понад 100 Мб

sudo find / -type f -size + 100000k -exec ls -lh {} \;

Знайдіть файли понад 10 Мб

sudo find / -type f -size + 10000k -exec ls -lh {} \;

Перша частина - це команда find за допомогою прапора "-size" для пошуку файлів різного розміру, виміряних у кілобайтах.

Останній біт в кінці, що починається з "-exec", дозволяє вказати команду, яку ми хочемо виконати для кожного знайденого нами файлу. Тут команда "ls -lh", щоб включити всю інформацію, яка з’являється при переліку вмісту каталогу. H до кінця особливо корисний, оскільки він виводить розмір кожного файлу у читаному для людини форматі.


2
Його проблема полягає у високому використанні inode, що вказує на багато менших файлів, а не великих.
UpTheCreek

0

Це працювало для мене, коли інший не працював на Android через оболонку:

find / -type d -exec sh -c "fc=\$(find '{}' -type f | wc -l); echo -e \"\$fc\t{}\"" \; | sort -nr | head -n25

0

Мені подобається використовувати щось на кшталт du --inodes -d 1пошуку каталогу, який або рекурсивно, або безпосередньо містить багато файлів.

Мені також подобається ця відповідь: https://unix.stackexchange.com/a/123052

Для ледачих нас ось суть цього:

du --inodes -S | sort -rh | sed -n \
    '1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/\1...\2/;p}'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.