Pull to refresh

Comments 10

Нюанс критичный, статья годная. Интересно только, что именно за процесс ускоряется в 40 раз.
Если это просмотр пользователем каталога из 10 000 файлов ценой удаления метаданных — сочувствую этому пользователю.
Если это какой-то автоматизированный процесс, использующий вывод ls в своих нуждах — я обязательно оставлю это здесь:
Не «удаления метаданных», а «не раскрашивания вывода ls на основании части метаданных»

На самом деле хороший вопрос. Зачем кому-то глазами смотреть 10000 файлов? По поводу скриптов: в статье сказано, что ls не использует раскраску при auto, если не выводится непосредственно в консоль.

Ну у меня такое бывает иногда (10-20к), нужно проверить, как скрипт отработал.
Я проводил некоторые исследования в области директорий с большим количеством файлов и могу сказать следующее:

  1. Современная ФС, такая как ext4 пережёвывает директории с любым количеством файлов без повреждений и заметной потери производительности. Проверял на десятках миллионов.
  2. Устаревшие ФС, такие как FAT32 могут при обращении к одному файлу тормозить линейно, а иногда и квадратично от к-ва файлов в папке
  3. Простейшим из быстрейших способов получить список файлов является вызов find без параметров, у ls надо читать ман и приказывать ему не сортировать список (и не раскрашивать, как понятно из статьи)
  4. Быстрейшим способом очистить такую директорию является rsync с пустой директорией. А rm * подвесит вам шелл. Если рсинка под рукой нет я бы попробовал find -delete или даже "rm -r .".
  5. Если вы используете ls --color или ls -l то вы не избежите вызова stat() на каждый файл, а это совсем не то же самое, что просто получить список имён.
  6. Если файлы созданы чем-то вроде touch {1..10000000} то их inode расположены подряд и stat() работает сравнительно быстро
  7. Если вы годами копили свои файлы (например, не чистили сессии php) то inode раскиданы по таблице и stat() будет очень медленным, особенно на НЖМД
  8. Вам не нужно читать глазами листинг директории с миллионом файлов. Даже парсить его не нужно, нет и не должно быть таких задач.
4. Если подождать несколько часов, то rm умрёт, сказав что не хватает памяти.  find – примерно та-же история. Единственным надёжным и быстрым способом является rsync с пустой.
Проверялось несколько лет назад на (очень) больших нечищеных кэшах squid.

Я еще заметил, что после удаления или перемещения файлов из конкретной папки, остаются inode записи (ну я думаю, что это они). Их видно в листинге 'ls -l' как большое число в первой строчке, которая начинается с точки и обозначает текущую директорию.
Вызов 'ls' в такой, вроде бы очищенной (а раньше в ней была пара миллионов файлов), папке занимает длительное время, даже если файлов внутри "уже нет".


Лечится удалением и пересоздание папки.


P.s. Ubuntu Server 14.04, ext4

Лечится удалением и пересоздание папки.
Да, как это часто бывает в IT, некоторые структуры данных могут расти но не обучены уменьшатся. 'e2fsck -D' по идее сожмёт такую директорию.
PS Это не inode, они сидят в своей таблице глобальной для всей ФС. Это имена файлов или места, где эти имена ранее были, ведь директория — это такой файл со списком имён файлов и номеров ячеек в таблице inode.
Быстрейшим способом очистить такую директорию является rsync с пустой директорией.
А rm * подвесит вам шелл. Если рсинка под рукой нет я бы попробовал find -delete или даже "rm -r .".

Нет, rsync не является быстрейшим.
unlink perl-a быстре, на выбор:


perl -e 'for(<*>){((stat)[9]<(unlink))}'
perl -e 'chdir "/var/spool/exim/msglog/" or die; opendir D, "."; while ($n = readdir D) { unlink $n }'

истоки

13 секунд пользователю съекономили… теперь он сможет намного больше файлов обработать за трудодень…
чего бы еще такого полезного замутить?
Sign up to leave a comment.

Articles