- Как удалить большое количество файлов в Linux
- Как быстро удалить Очень Много файлов?
- Re: Как быстро удалить Очень Много файлов?
- Каждую неделю вопрос на ЛОРе.
- Use ionice, Luke!
- Re: Как быстро удалить Очень Много файлов?
- Быстрое удаление каталога с огромным количеством вложенных файлов и подкаталогов
- Команды для удаления большого количества файлов в Linux
- Удаление старых файлов в Linux по Cron
- Так как же удалить миллионы файлов из одной папки?
- Подготовка
- Тесты
- Удаление через rm -r
- Удаление через rm ./*
- Удаление через find -exec
- Удаление через find -delete
- Удаление через ls -f и xargs
- Удаление через perl readdir
- Удаление через программу на C readdir + unlink
Как удалить большое количество файлов в Linux
Удалять файлы можно используя утилиту find, в отличие от ls или rm с указанием маски она не формирует изначально список содержимого каталога, а перебирает файлы по одному.
Посчитать количество файлов можно так
find /home/web/example.com/www/opt/cache/ -type f ¦ wc -l
С -exec rm -f можно запустить процесс удаления файлов (он может занять длительное время)
find /home/web/example.com/www/opt/cache/ -type f -exec rm -f <> \;
Можно попробовать find с опцией delete
find /home/web/example.com/www/opt/cache/ -type f -delete
Скорее всего не даст никакого результата rm с указанием файлов по маске — система при этом до того как начать удаление попытается сформировать полный список файлов, что сделать не получится
Также существует вариант с ls -f, вывод которого перенаправляется в xargs по 100 файлов, затем удаляемых при помощи rm. Может успешно отрабатывать, однако если файлов слишком много вывести список не получится и с ls -f
cd /home/web/example.com/www/opt/cache/ ; ls -f . | xargs -n 100 rm
Самой эффективной командой обычно оказывается find с -exec rm -f, однако все зависит от количества файлов и использовать стоит все представленные варианты (приоритет процессов при удалении имеет смысл максимально понижать используя nice и ionice — алиасы для find или других команд можно добавить в .bashrc пользователя, от имени которого производится удаление).
Источник
Как быстро удалить Очень Много файлов?
Есть раздел под XFS. В нём директория. Выглядит так:
# ls -ldh .
drwxrwxrwx 2 user user 330M Aug 4 01:04
Т.е. только мета-инфа весит 330 Мб (верхняя планка, значит, 1,3-1,4 млн. файлов). Списка имён файлов нет.
Вопрос: как их быстро удалить, с минимальной утилизацией винтов (продакшн-сервер) и без потери остальных данных на этом разделе?
Re: Как быстро удалить Очень Много файлов?
rm -dfr /var/www или че там у тебя
Каждую неделю вопрос на ЛОРе.
Этого вопроса ещё нет в FAQ? (Мне лень смотреть)
find . -maxdepth 1 -type f | xargs -0 ls
Use ionice, Luke!
> Т.е. только мета-инфа весит 330 Мб
Неверно, но к делу отношения не имеет.
> Вопрос: как их быстро удалить,
rm -rf /path/to/dir
> с минимальной утилизацией винтов (продакшн-сервер)
echo cfq > /sys/block/[диск, где находится ФС]/queue/scheduler
ionice -c3 rm -rf /path/to/dir
P.S. Непонятно, чем они так помешали, что понадобилось их так срочно удалять.
Re: Как быстро удалить Очень Много файлов?
Спасибо. С -d всё хорошо.
До этого пробовал:
#find ./ -maxdepth 1 -type f -mtime +7 -exec rm -f <> \;
(не хотелось удалять всё), выглядело так:
——————
#strace -s 360 -p 25670
Process 25670 attached — interrupt to quit
getdents64(4, /* 73 entries */, 4096) = 4088
getdents64(4, /* 73 entries */, 4096) = 4088
getdents64(4, /* 73 entries */, 4096) = 4088
getdents64(4, /* 73 entries */, 4096) = 4088
getdents64(4, /* 73 entries */, 4096) = 4088
etdents64(4,
Process 25670 detached
——————
, т.е. видимо строило файл-лист и делало это больше недели, с обычным rm было так же (надо было кстати использование памяти замерить).
А с ionice -c3 rm -dfr dir так:
# strace -s 360 -p 933
——————
Process 933 attached — interrupt to quit
unlink(«4e2a0e62921574187660e5ea2155af7e») = 0
unlink(«6094ad144713c973537c162b9e52b5d5») = 0
unlink(«86287687383af5b9c880cd6d4dbaca1c») = 0
unlink(«a8c6a06559e542e396c01a28d6110bbc») = 0
unlink(«ce40f028183e656e1fb5039b8a06dc92») = 0
unlink(«6c66c8ac651afbcd9c3b6dd45a79d506») = 0
unlink(«0753b1f1fcadc9262f0705c897350846») = 0
unlink(«a76ec71296a85087c5e76c413c92e23b») = 0
unlink(«66d65eba60a15d3e44b4058c763dbe74») = 0
— SIGINT (Interrupt) @ 0 (0) —
Process 933 detached
——————
Источник
Быстрое удаление каталога с огромным количеством вложенных файлов и подкаталогов
Столкнулся с проблемой следующего рода:
Имеется каталог, с большим количеством подкаталогов и уровнем вложенности который определить не представляется возможным.
Общий размер каталога около 20Гб, количество файлов более 10 млн. Точное количество файлов определить не хватило терпения (более 3 часов ждал, не долждался), а размер определил методом: вычесть из общего размера занятого на диске размер прочих каталогов, чей размер определить удалось.
Задача: удалить этот каталог со всем его содержимым за минимальный промежуток времени и с минимальным износом ЖД (все это дело на ноутбуке).
пробовал сделать «rm -rfd folder_name», ждал 3 часа, освободило не более 3 Гб и с каждым часом скорость очистки замедлялась.
Может кто другие, более производительные методы подскажет?
перенести все остальное на другой винт, а этот форматнуть и впредь так не делать
подробнее пожалуйста, если можно?
а) +1 за идею забэкапить все кроме этого каталога, снести все нафиг, восстановить все кроме каталога
б) поставить rm -rf на ночь или выходные и не париться, ничего жесткому диску не будет
А по inode-у удалить разве нельзя? Грохни inode каталога и все, прощай файлики. How to: Linux / UNIX Delete or Remove Files With Inode Number
ждал 3 часа, освободило не более 3 Гб
Ну подожди еще сутки. Можно подумать, ты эти три часа педали крутил чтоб оно удалялось.
И дальше по теме 🙂
Ну, или для Ъ — rsync
Стандартное решение: unlink верхней директории, следом umount и fsck.
unlink не работает с каталогами
Дык, я только что сидел, пытался. Оказывается, поломали, сволочи!
Надо восстановить справедливость и пропатчить glibc, чтобы unlink перестал проверять, является ли хрень по указанному адресу директорией, если его запускают от рута.
или ты имел в виду сискол?
Да пофиг. Главное — поломали же такую классную вещь.
потом fsck скажет что ему вусмерть надо поработать и вернет всё в lost+found
Чушь. И да, на reiserfs нет директории lost&found!
А про износ диска ТС-у никто не ответил. Может ему нужно перемонтировать ФС или что написать в /proc, чтобы было усиленное кеширование записи?
Такое вытворял не я, а человек работавший ранее на этом рабочем месте. Сносить все это хозяйство опять же не предоставляется возможным, слишком много инфы + / & /home в одном разделе, так что.
Я не думаю, что разовое удаление такого каталога заметно скажется на износе диска.
А вот если задача становится многократно, я бы посоветовал посмотреть в сторону reisrefs. Мне часто приходится работать с кешами, когда несколько десятков или сотен тысяч файлов на несколько гигабайт или десятков гигабайт лежат в на 2-3 уровнях вложенности в подкаталогах. ext4 на такой структуре через какое-то время использования становится адом. Я несколько лет мучился, пока не рискнул reisrefs проверить, памятуя, что лет 10-15 назад серьёзных проблем с такими структурами (с небольшими поправками на развитие железа) у меня не было. А вправду, одна только синхронизация по rsync на таких объёмах, занимая на ext4 десяток минут, на reiserfs отрабатывает за минуту. Даже (на машинах без lvm, когда легко не переразбить диск) быстрее оказывается в плане скорости поставить reisrefs в файл-образ на ext4.
Источник
Команды для удаления большого количества файлов в Linux
Удаление старых файлов linux по маске чаще всего осуществляется следующим образом:
Веб-сервер указан для примера. Синтаксис очень прост — команда принудительно удалит все файлы с расширением .log в указанном каталоге, при этом удаление будет рекурсивным(-r — recursive) и подтверждения система при этом спрашивать не будет (-f — force).
При удалении таким образом очень большого количества файлов из определенного каталога может выдавать ошибки — причина в том, что система на самом деле не видит маски и разворачивает передаваемое ей выражение — срабатывает ограничение на количество аргументов, и выполнение команды прекращается.
Если rm -rf не помогает — удалять файлы следует в цикле for. Для каждого файла будет отдельная операция удаления и никаких ограничений системы здесь ожидать не приходится.
Синтаксис в простейшем случае может выглядеть так:
for f in /var/log/apache2/*.log; do rm «$f»; done
В цикл for можно добавить любую дополнительную логику.
Удаление старых файлов в Linux по Cron
Логи или другие файлы (сессии РНР) можно удалять как используя циклы (так приходится делать обычно если логов или других файлов накопилось действительно очень много), но если система не запущена или только создается лучше использовать регулярно выполняемое задание Cron, согласно которому с заданной периодичностью будут удаляться файлы определенных типов
# m h dom mon dow command
23 3 * * * find /var/www/web/sites/server-gu.ru/www/var/session/ -type f -mtime 7 -exec rm -f <> \;
В примере удаляются сессии РНР для сайта старше 7 дней.
В цикле то же самое можно сделать так:
for f in /tmp/logs/*.log
find $f -mtime +7 -exec rm <> \;
Приведенное выражение, как и любой другой цикл можно поместить в файл, сделать его исполняемым и с тем же успехом выполнять по Cron
Источник
Так как же удалить миллионы файлов из одной папки?
Феерическая расстановка точек над i в вопросе удаления файлов из переполненной директории.
Прочитал статью Необычное переполнение жесткого диска или как удалить миллионы файлов из одной папки и очень удивился. Неужели в стандартном инструментарии Linux нет простых средств для работы с переполненными директориями и необходимо прибегать к столь низкоуровневым способам, как вызов getdents() напрямую.
Для тех, кто не в курсе проблемы, краткое описание: если вы случайно создали в одной директории огромное количество файлов без иерархии — т.е. от 5 млн файлов, лежащих в одной единственной плоской директории, то быстро удалить их не получится. Кроме того, не все утилиты в linux могут это сделать в принципе — либо будут сильно нагружать процессор/HDD, либо займут очень много памяти.
Так что я выделил время, организовал тестовый полигон и попробовал различные средства, как предложенные в комментариях, так и найденные в различных статьях и свои собственные.
Подготовка
Так как создавать переполненную директорию на своём HDD рабочего компьютера, потом мучиться с её удалением ну никак не хочется, создадим виртуальную ФС в отдельном файле и примонтируем её через loop-устройство. К счастью, в Linux с этим всё просто.
Создаём пустой файл размером 200Гб
Многие советуют использовать для этого утилиту dd, например dd if=/dev/zero of=disk-image bs=1M count=1M , но это работает несравнимо медленнее, а результат, как я понимаю, одинаковый.
Форматируем файл в ext4 и монтируем его как файловую систему
К сожалению, я узнал об опции -N команды mkfs.ext4 уже после экспериментов. Она позволяет увеличить лимит на количество inode на FS, не увеличивая размер файла образа. Но, с другой стороны, стандартные настройки — ближе к реальным условиям.
Создаем множество пустых файлов (будет работать несколько часов)
Кстати, если в начале файлы создавались достаточно быстро, то последующие добавлялись всё медленнее и медленнее, появлялись рандомные паузы, росло использование памяти ядром. Так что хранение большого числа файлов в плоской директории само по себе плохая идея.
Проверяем, что все айноды на ФС исчерпаны.
Размер файла директории
Теперь попробуем удалить эту директорию со всем её содержимым различными способами.
Тесты
После каждого теста сбрасываем кеш файловой системы
sudo sh -c ‘sync && echo 1 > /proc/sys/vm/drop_caches’
для того чтобы не занять быстро всю память и сравнивать скорость удаления в одинаковых условиях.
Удаление через rm -r
$ rm -r /mnt/test_dir/
Под strace несколько раз подряд (. ) вызывает getdents() , затем очень много вызывает unlinkat() и так в цикле. Занял 30Мб RAM, не растет.
Удаляет содержимое успешно.
Т.е. удалять переполненные директории с помощью rm -r /путь/до/директории вполне нормально.
Удаление через rm ./*
$ rm /mnt/test_dir/*
Запускает дочерний процесс шелла, который дорос до 600Мб, прибил по ^C . Ничего не удалил.
Очевидно, что glob по звёздочке обрабатывается самим шеллом, накапливается в памяти и передается команде rm после того как считается директория целиком.
Удаление через find -exec
$ find /mnt/test_dir/ -type f -exec rm -v <> \;
Под strace вызывает только getdents() . процесс find вырос до 600Мб, прибил по ^C . Ничего не удалил.
find действует так же, как и * в шелле — сперва строит полный список в памяти.
Удаление через find -delete
$ find /mnt/test_dir/ -type f -delete
Вырос до 600Мб, прибил по ^C . Ничего не удалил.
Аналогично предыдущей команде. И это крайне удивительно! На эту команду я возлагал надежду изначально.
Удаление через ls -f и xargs
$ cd /mnt/test_dir/ ; ls -f . | xargs -n 100 rm
параметр -f говорит, что не нужно сортировать список файлов.
Создает такую иерархию процессов:
ls -f в данной ситуации ведет себя адекватнее, чем find и не накапливает список файлов в памяти без необходимости. ls без параметров (как и find ) — считывает список файлов в память целиком. Очевидно, для сортировки. Но этот способ плох тем, что постоянно вызывает rm , чем создается дополнительный оверхед.
Из этого вытекает ещё один способ — можно вывод ls -f перенаправить в файл и затем удалить содержимое директории по этому списку.
Удаление через perl readdir
$ perl -e ‘chdir «/mnt/test_dir/» or die; opendir D, «.»; while ($n = readdir D) < unlink $n >‘ (взял здесь)
Под strace один раз вызывает getdents() , потом много раз unlink() и так в цикле. Занял 380Кб памяти, не растет.
Удаляет успешно.
Получается, что использование readdir вполне возможно?
Удаление через программу на C readdir + unlink
$ gcc -o cleandir cleandir.c
$ ./cleandir
Под strace один раз вызывает getdents() , потом много раз unlink() и так в цикле. Занял 128Кб памяти, не растет.
Удаляет успешно.
Опять — же, убеждаемся, что использовать readdir — вполне нормально, если не накапливать результаты в памяти, а удалять файлы сразу.
Источник