LINUX.ORG.RU
ФорумAdmin

Как быстро удалить Очень Много файлов?


0

1

Есть раздел под XFS. В нём директория. Выглядит так:

# ls -ldh .
drwxrwxrwx 2 user user 330M Aug 4 01:04

Т.е. только мета-инфа весит 330 Мб (верхняя планка, значит, 1,3-1,4 млн. файлов). Списка имён файлов нет.

Вопрос: как их быстро удалить, с минимальной утилизацией винтов (продакшн-сервер) и без потери остальных данных на этом разделе?

anonymous

Каждую неделю вопрос на ЛОРе.

Этого вопроса ещё нет в FAQ? (Мне лень смотреть)

find . -maxdepth 1 -type f | xargs -0 ls

man find

man xargs

lodin ★★★★
()

Use ionice, Luke!

> Т.е. только мета-инфа весит 330 Мб

Неверно, но к делу отношения не имеет.

> Вопрос: как их быстро удалить,

rm -rf /path/to/dir

> с минимальной утилизацией винтов (продакшн-сервер)

echo cfq > /sys/block/[диск, где находится ФС]/queue/scheduler

ionice -c3 rm -rf /path/to/dir

P.S. Непонятно, чем они так помешали, что понадобилось их так срочно удалять.

Dselect ★★★
()
Ответ на: комментарий от anonymous

Спасибо. С -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, <unfinished ...>
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
------------------

anonymous
()

Телепаты в отпуске.

> и без потери остальных данных на этом разделе?

Не понял -- при чём тут раздел? Уточните вопрос.

Dselect ★★★
()
Ответ на: Use ionice, Luke! от Dselect

>>rm -rf /path/to/dir

Слишком долго, оно сперва строит список файлов (м.б. дело в версии fileutils, машинка старая, давно не обновлялась). Плюс возможно всё вылетело бы в OOM -- не проверял, впрочем.

>>P.S. Непонятно, чем они так помешали, что понадобилось их так срочно удалять.

rsync с внешнего хоста, к которому нет доступа (следовательно нет возможности эксклюднуть диру).

anonymous
()
Ответ на: комментарий от anonymous

Маленький мальчик на лифте катался, всё хорошо, только трос оборвался.

> Спасибо. С -d всё хорошо.

Ага, только ФС малость запорота, а так да -- всё хорошо.

> #find ./ -maxdepth 1 -type f -mtime +7 -exec rm -f {} \;

Вы на каждый удаляемый файл создавали по процессу...

> видимо строило файл-лист и делало это больше недели,

... мне почему-то кажется, что оно (ядро) в бешенном темпе процессы рожало.

> А с ionice -c3

ionice -c3 -- это чтоб оно не мешало другим процессам, и лезло к диску только тогда, когда он ничем не занят.

Dselect ★★★
()
Ответ на: комментарий от anonymous

mount --bind

> rsync с внешнего хоста, к которому нет доступа (следовательно нет 
> возможности эксклюднуть диру).

Проще было нужные файлы в отдельную директорию сложить, как-нибудь так:

cd /path/to/fs
mkdir useful_files
mv a b c d useful_files

И спрятать ненужные:

cd /
mount --move /path/to/fs /mnt
mkdir -p /path/to/fs
mount --bind /mnt/useful_files /path/to/fs

И потом спокойно, не торопясь, удалять мусор из /mnt. Например, так:

find /mnt -maxdepth 1 -type f | xargs -n8192 rm -f

Dselect ★★★
()

>>Вы на каждый удаляемый файл создавали по процессу...
>>... мне почему-то кажется, что оно (ядро) в бешенном темпе процессы рожало.

Нет, до спауна rm-ов дело даже не доходило.

>>ionice -c3 -- это чтоб оно не мешало другим процессам

Я знаю про IO scheduler и достаточно давно и активно использую ionice с idle-приоритетом.

>>Ага, только ФС малость запорота, а так да -- всё хорошо.

Почему? Как этого избежать?

anonymous
()

Just for fun

Смеху ради запустил такой скриптик:

##### кусь - кусь - кусь ####
#/bin/sh -e
mkdir -p test
cd test
i=0
F_MAX=1000000
while test $i -lt $F_MAX; do
	touch $i
	i=$(expr $i + 1)
done

cd ..
ls -shd test

##### кусь - кусь - кусь ####

Он мне выдал

40M test

Вот я и прикидываю -- а сколько ж у Вас там файлов-то было?

Dselect ★★★
()
Ответ на: mount --bind от Dselect

>>Проще было нужные файлы в отдельную директорию сложить

К сожалению, это достаточно активно используемый и значительный по объёму контент. Такая операция займёт какое-то врёмя (опять же -- хотя-бы список файлов для мува построить), а даунтайм очень нежелателен.

Впрочем, с маунтом хорошая идея, можно будет попробовать прибайндить что-нибудь пустое поверх этой дурацкой диры, прогнать синк, а потом разбираться. Спасибо.

anonymous
()
Ответ на: Just for fun от Dselect

>>Вот я и прикидываю -- а сколько ж у Вас там файлов-то было?

Вы на XFS опыт проводили? (На ней ещё ужаа-а-а-асно медленный анлинк, а с ядрами 2.6.18+ кернелпаники раз в неделю. К сожалению переехать пока не можем.).

anonymous
()
Ответ на: комментарий от anonymous

> Впрочем, с маунтом хорошая идея, можно будет попробовать прибайндить что-нибудь пустое поверх этой дурацкой диры,

Если там вообще ничего полезного нет, не обязательно и bind'ить, просто смонтировать пустую ФС:

mount -t tmpfs -o rw,nodev,nosuid,noexec,mode=0755,size=1M STUB /path/to/fs/stupid_dir

А для расчистки -- таки

mount --bind /path/to/dir /mnt

cd /mnt/stupid_dir

## чего-нибудь тут сделать.

Dselect ★★★
()
Ответ на: комментарий от anonymous

> Вы на XFS опыт проводили?

Да. Другие ФС обломаются столько файлов в одной директории создать :)

> На ней ещё ужаа-а-а-асно медленный анлинк

Не совсем правда. Удаление _больших_ файлов весьма таки шустро происходит. Другое дело, что каждый unlink -- это операция с мета-данными, и его нужно в журнал записать... Потому удаление ~ 10 миллионов файлов -- таки да, займёт некоторое время.

> а с ядрами 2.6.18+ кернелпаники раз в неделю.

$ mount | grep xfs | wc -l

1

$ uptime

19:23:03 up 72 days, 3:42, 7 users, load average: 3.22, 3.07, 3.02

$ uname -r

2.6.18-6-amd64

Что я делаю не так?

Dselect ★★★
()
Ответ на: комментарий от Dselect

>>2.6.18-6-amd64

Некорректно написал: старше 2.6.18, не включая её. У нас сейчас 2.6.18.2. Для более старших версий были паники (ядра все были самосбор, не вендорные; паники наблюдались на четырёх разных машинах).

anonymous
()
Ответ на: Just for fun от Dselect

чего тут прикидывать? элементарная математика же!

anonymous
()

самый быстрый способо: find /path -type f -delete

остальное всё шлак ибо лищние форки сильно тормозят процесс.

true_admin ★★★★★
()
Ответ на: Just for fun от Dselect

А можете (чисто из академического интереса) запустить
-----------------------
mkdir test
i=0; while [ $((++i)) -lt 1000000 ]; do touch mkdir/`echo $i|md5sum|cut -d" " -f 1`; done
ls -shd test
-----------------------
?

Интересна (не)зависимость числа от средней длинны имени файла.

anonymous
()
Ответ на: комментарий от true_admin

Ещё раз: find предварительно строит файл-лист. На это, во-первых, уходит больше недели на таком числе файлов (эмпирически установленно), а во-вторых, делает он это в памяти (RSS растёт достаточно шустро). Если за эту неделю произойдёт сбой любого характера -- начинай сначала.

anonymous
()
Ответ на: комментарий от anonymous

>Ещё раз: find предварительно строит файл-лист

а кто знает как чтобы не строился лист а сразу command?

anonymous
()
Ответ на: комментарий от anonymous

Что команд ls тоже неделю думает, прежде чем список выплевывать начинает?
Если да, то можно попробовать
 perl:
   opendir
   while (readdir) {
      unlink
   }

sdio ★★★★★
()
Ответ на: комментарий от sdio

$ cd /tmp/test
$ ls aaa | wc -l
2000000
$ cd aaa
$ time perl -e 'opendir(D1, "/tmp/test/aaa") || die "Error: $!"; readdir(D1); readdir(D1); while ($a=readdir(D1)) { unlink("$a");}'

real    19m38.814s
user    0m14.137s
sys     4m5.607s

У тебя на порядок больше файлов, так что часа 3-4 уйдет на их удаление.

sdio ★★★★★
()
Ответ на: комментарий от anonymous

> Ещё раз: find предварительно строит файл-лист

да ну? у меня не строил. Проверено на папке с лимоном файлов.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

М.б. это version specific.
# find --version
GNU find version 4.2.20
Features enabled: D_TYPE O_NOFOLLOW(enabled)

Фрагмент strace приводил.

anonymous
()
Ответ на: комментарий от sdio

А CPU тут причём? Disk utilization 100% (iostat -x 2).

Удаляется вторые сутки. Иногда приходится тормозить процесс -- даже с idle-приоритетом (ionice -c3) удаление изрядно тормозит систему (а это, как назло, активно используемый файл-сервер).

anonymous
()
Ответ на: комментарий от sdio

Проверил -- обычный rm из относительно свежих coreutils работает пошустрее и ресурсов ест поменьше (всё-таки C), хотя делает тот же readdir/unlink. Видимо, всё упирается в скорость работы системных вызовов, а они -- в скорость работы XFS с метаданными и дисковый ввод-вывод. Поэтому ускорить операцию выйдет вряд-ли.

Разве что какие опции монтирования. Сейчас вот так:
# mount|grep xfs|cut -d"(" -f 2
rw,noatime,nodiratime,osyncisdsync,logbufs=8,nobarrier)

anonymous
()
Ответ на: комментарий от anonymous

> Фрагмент strace приводил.

мда, у меня тоже, вроде, всё за раз считывает. Странно, а папку с димоном файлов удалил быстро. Судя по strace, считать содержимое папки не такое уж долгое занятие. Но сортировку файлов он не делает, в этом легко убедиться.

true_admin ★★★★★
()

После четырёх дней решил проверить сколько удалилось (остановился на обычном rm -vfr из обновлённых coreutils). Было изначально, как удалось выяснить, ~7 млн. 100 тыс.
----------------
#ionice -c3 perl -e 'opendir(D1, "/var/www/auctions.vl.ru/new/app/tmp/sessions") || die "Error: $!"; wa=readdir(D1)) { $i+=1; if ($i%10000 == 0) {print $i."\n"; };}; print $i."\n";'
[...]
4330000
4339120
----------------

За четыре дня всего 3 млн. (удалялось с минимальным приоритетом на загруженной машине).

anonymous
()
Ответ на: комментарий от anonymous

Интересно, что за железо, т.к. у меня на домашней средней мощности тачке 1млн файлов удаляется за 10мин.

sdio ★★★★★
()
Ответ на: комментарий от sdio

RAID 5 (LSI) на 15k SCSI-винтах. Дело, повторяюсь, в огромной дисковой нагрузке от основных сервисов.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.