Предыстория: физический сервер, около двух лет, диски SATA 7200 об / мин, подключенные к RAID-карте 3Ware, noatime с установленной файловой системой ext3 FS и данные = заказано, без сумасшедшей нагрузки, ядро 2.6.18-92.1.22.el5, время безотказной работы 545 дней , Каталог не содержит никаких подкаталогов, только миллионы маленьких (~ 100 байт) файлов, с некоторыми большими (несколько КБ).
У нас есть сервер, который за последние несколько месяцев немного кукушка, но мы заметили это только на днях, когда он не смог выполнить запись в каталог из-за слишком большого количества файлов. В частности, он начал выдавать эту ошибку в / var / log / messages:
ext3_dx_add_entry: Directory index full!
На рассматриваемом диске осталось много инодов:
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda3 60719104 3465660 57253444 6% /
Так что я предполагаю, что это означает, что мы достигли предела того, сколько записей может быть в самом файле каталога. Не знаю, сколько будет файлов, но, как видите, не может быть больше, чем три миллиона или около того. Не то чтобы это хорошо, заметьте! Но это первая часть моего вопроса: что это за верхний предел? Это настраивается? Прежде чем орать на меня - я хочу смягчить это ; этот огромный каталог вызвал всевозможные проблемы.
В любом случае, мы отследили проблему в коде, который генерировал все эти файлы, и исправили его. Теперь я застрял с удалением каталога.
Несколько вариантов здесь:
rm -rf (dir)
Я попробовал это первым. Я сдался и убил его после того, как он проработал полтора дня без какого-либо заметного воздействия.
- unlink (2) для каталога: безусловно, стоит подумать, но вопрос в том, будет ли быстрее удалять файлы внутри каталога через fsck, чем удалять через unlink (2). То есть, так или иначе, я должен пометить эти inode как неиспользованные. Это предполагает, конечно, что я могу сказать fsck не сбрасывать записи в файлы в / lost + found; в противном случае я просто перенес свою проблему. В дополнение ко всем другим проблемам, после прочтения об этом, оказывается, что мне, вероятно, придется вызывать некоторые внутренние функции FS, поскольку ни один из найденных мной вариантов unlink (2) не позволил бы мне просто беспечно удалить каталог с записями в нем. Пух.
while [ true ]; do ls -Uf | head -n 10000 | xargs rm -f 2>/dev/null; done )
Это на самом деле сокращенная версия; Реальный, который я запускаю, который просто добавляет отчеты о прогрессе и чистую остановку, когда у нас заканчиваются файлы для удаления, это:
экспорт я = 0; время (в то время как [верно]; сделать ls -Uf | голова -n 3 | grep -qF '.png' || сломать; ls -Uf | голова -n 10000 | xargs rm -f 2> / dev / null; export i = $ (($ i + 10000)); echo "$ i ..."; сделанный )
Кажется, это работает довольно хорошо. Когда я пишу это, он удалил 260 000 файлов за последние тридцать минут или около того.
- Как упомянуто выше, настраивается ли ограничение на количество записей в каталоге?
- Почему потребовалось «реальные 7m9.561s / пользователь 0m0.001s / sys 0m0.001s», чтобы удалить один файл, который был первым в списке, возвращаемом пользователем
ls -U
, и, возможно, потребовалось десять минут, чтобы удалить первые 10000 записей с команда в # 3, но теперь она довольно счастливо тащится? В этом отношении он удалил 260 000 примерно за тридцать минут, но теперь требуется еще пятнадцать минут, чтобы удалить еще 60 000. Почему огромные колебания в скорости? - Есть ли лучший способ сделать это? Не хранить миллионы файлов в каталоге; Я знаю, что это глупо, и это не случилось бы на моих часах. Погугление проблемы и просмотр SF и SO предлагает множество вариантов
find
, которые не будут значительно быстрее моего подхода по нескольким очевидным причинам. Но есть ли у идеи delete-via-fsck ноги? Или что-то еще целиком? Мне не терпится услышать нестандартное (или не очень известное) мышление.
Окончательный вывод сценария !:
2970000...
2980000...
2990000...
3000000...
3010000...
real 253m59.331s
user 0m6.061s
sys 5m4.019s
Таким образом, три миллиона файлов были удалены за чуть более четырех часов.
rm -rfv | pv -l >/dev/null
, PV должен быть доступен в репозитории EPEL .