Найти каталоги с большим количеством файлов в

Итак, мой клиент получил электронное письмо от Linode сегодня, в котором говорилось, что его сервер вызывает взлом службы резервного копирования Linode. Зачем? Слишком много файлов. Я рассмеялся и затем побежал:

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

Дерьмо. 2,4 миллиона Inode в использовании. Что, черт возьми, происходит?!

Я искал очевидных подозреваемых (/var/{log,cache} и каталог, где размещены все сайты), но я не нахожу ничего действительно подозрительного. Где-то на этом звере я уверен, что есть каталог, который содержит пару миллионов файлов.

Для контекста один мои мои занятые серверы используют 200 тыс. Инодов, а мой рабочий стол (старая установка с более чем 4 ТБ используемого хранилища) составляет чуть более миллиона. Есть проблема.

Итак, мой вопрос, как мне найти, где проблема? Есть ли du для инодов?

33
задан 3 July 2013 в 23:32

7 ответов

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

Проверить iostat видеть, производит ли некоторое приложение все еще файлы как сумасшедший.

find / -xdev -type d -size +100k скажет Вам, если будет каталог, который использует больше чем 100 КБ дискового пространства. Это было бы каталогом, который содержит много файлов или содержал много файлов в прошлом. Можно хотеть скорректировать число размера.

Я не думаю, что существует комбинация опций к GNU du сделать это количеством 1 на запись каталога. Можно сделать это путем создания списка файлов с find и делая определенный подсчет в awk. Вот a 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 скажет Вам крупнейших преступников.

23
ответ дан 3 July 2013 в 23:32

Это сработало для меня, когда другой не удалось на Android через оболочку:

find / -type d -exec sh -c "fc=\$(find '{}' -type f | wc -l); echo -e \"\$fc\t{}\"" \; | sort -nr | head -n25
0
ответ дан 3 July 2013 в 23:32

Другой предлагает:

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

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

Найдите файлы более чем 1 ГБ

sudo находят / - тип f - размер +1000000k - должностное лицо ls - люфтганза {} \;

Найдите файлы более чем 100 МБ

sudo находят / - тип f - размер +100000k - должностное лицо ls - люфтганза {} \;

Найдите файлы более чем 10 МБ

sudo находят / - тип f - размер +10000k - должностное лицо ls - люфтганза {} \;

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

Последнее обдумало конец, запускающийся с "-должностное лицо" позволяет указывать команду, которую мы хотим выполнить на каждом файле, который мы находим. Здесь "ls - люфтганза" управляют для включения всей информации, видящей при списке содержания каталога. H к концу особенно полезен, поскольку он распечатывает размер каждого файла в человекочитаемом формате.

1
ответ дан 3 July 2013 в 23:32

Мне нравится использовать что-то вроде 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}'
0
ответ дан 3 July 2013 в 23:32

Можно свериться с этим сценарием:

#!/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:

top-bushy-folders

14
ответ дан 3 July 2013 в 23:32

Часто быстрее, чем поиск, если ваша база данных locate обновлена:

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

Это выдает всю базу данных locate, удаляет все, что находится за последним символом / в пути, затем сортирует и "uniq -c" выдает количество файлов / каталогов на один каталог. «sort -n» отправляется в хвост, чтобы получить десять каталогов с наибольшим количеством вещей в них.

0
ответ дан 3 July 2013 в 23:32

немного старая тема, но интересная, поэтому предлагаю свои решения.

Первый использует несколько команд, передаваемых по конвейеру, и находит каталоги с более чем 1000 файлами внутри:

find / -type d  |awk '{print "echo -n "$0" ---- ; ls -1 "$0" |wc -l "}'|bash |awk -F "----" '{if ($2>1000) print $1}'

Второй простой. Просто попробуйте найти каталоги размером более 4096 байт. Обычно пустой каталог имеет размер 4096 байт в файловой системе ext4 и 6 байт в xfs:

find / -type d -size +4096c

Вы, конечно, можете изменить это, но я считаю, что в большинстве случаев это должно работать с таким значением.

4
ответ дан 25 May 2020 в 00:44

Другие вопросы по тегам:

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