пятница, 16 сентября 2011 г.

Как удалить 1,5 миллиона файлов?

Вопрос, вынесенный в заголовок, недавно встал во весь рост довольно-таки приличной проблемой. 

Преамбула.

Есть почтовый сервер, который плодит в большом количестве мелкие логи сообщений и событий. Этот сервер установлен на раздел UFS, на котором внезапно кончаются inodes. Задолго до исчерпания, собственно, объема раздела. Как следствие, почтовик перестал нормально функционировать.

Задача - нужно удалить эти полтора миллиона мелких файлов (не более 1-4 Кб) с раздела, дабы сервер мог продолжать свою работу.

Проблема в следующем. Файлы лежат в одной директории. Если вы попытаетесь просто сделать ls - два часа ожидания. Пытаетесь сделать rm -f * из bash - segmentation fault. Пытаетесь сделать то же самое из Борна - too many arguments. Пытаетесь удалить директорию - rm -R - несколько часов ожидания и результат не гарантирован.

Сюрприз - никсы не рассчитаны на такое количество файлов в одной директории. Чтение метаданных занимает циклопическое время. А команды юзерлэнда даже представить не могут, что может столько файлов вообще быть принято к обработке.

Как решить проблему?

На UFS есть трюковый ход. 

unlink имя_директории

Три секунды и все. Директория со всем содержимым удалена, файлов нет, создаем директорию заново и даем на нее прежние права.

ВНИМАНИЕ! Не пытайтесь повторить это дома! В случае ошибки любая директория, включая системную, будет удалена со всем содержимым мгновенно и безвозвратно!

Имейте в виду. Данный прием работает ТОЛЬКО на ufs.

На zfs вы получите сообщение not owner:

root @ ktulhu /data # mkdir test
root @ ktulhu /data # unlink test
unlink: Not owner


Кстати, удаление директории с очень большим количеством файлов будет длительным на zfs тоже, несмотря на кэширование и все остальное. Более того, на zfs, с ее CoW, удаление может замедлиться в еще большей степени при сильном заполнении пула/датасета.

Мораль проста. Не плодите большого количества файлов в одной директории. Большинство ОС просто не рассчитаны на это. Кстати, приложения, работающие с файлами, тоже могут серьезно тормозить при доступе к таким директориям.