Удаление миллиардов файлов из каталога, а также наблюдение за прогрессом


36

У меня есть каталог на 30 ТБ, содержащий миллиарды файлов, которые формально являются файлами JPEG. Я удаляю каждую папку файлов следующим образом:

sudo rm -rf bolands-mills-mhcptz

Эта команда просто запускается и ничего не показывает, работает она или нет.

Я хочу видеть, как это удаление файлов или каков текущий статус команды.


19
Не ответы: иногда быстрее создать резервную копию того, что вы хотите сохранить, отформатировать и восстановить то, что вы хотите сохранить. Другие ответы: unix.stackexchange.com/questions/37329/…
Эрик Тауэрс

2
Если вы просто хотите получить представление о прогрессе, а не знать, какие именно файлы были удалены, вы можете запустить «df / dev / sd_whwhat_the_drive_is».
jamesqf

11
Как вы получили миллиарды файлов в одном каталоге?
Легкость гонки с Моникой

1
@MichaelHampton Но если файлы не являются отдельным набором данных, это может занять много времени. (на ZFS) serverfault.com/questions/801074/…
v7d8dpo4

5
Миллиарды файлов, а? Попробуй rm -ri. Это будет весело!
OldBunny2800

Ответы:


98

Вы можете использовать, rm -vчтобы rmраспечатать по одной строке на файл. Таким образом, вы можете увидеть, что rmдействительно работает для удаления файлов. Но если у вас есть миллиарды файлов, все, что вы увидите, это то, что rmвсе еще работает. Вы не будете знать, сколько файлов уже удалено и сколько осталось.

Инструмент pvможет помочь вам с оценкой прогресса.

http://www.ivarch.com/programs/pv.shtml

Вот как вы бы вызвать rmс pvс выходом , например ,

$ rm -rv dirname | pv -l -s 1000 > logfile
562  0:00:07 [79,8 /s] [====================>                 ] 56% ETA 0:00:05

В этом надуманном примере я сказал, pvчто есть 1000файлы. Выходные данные pvпоказывают, что 562 уже удалены, истекшее время составляет 7 секунд, и оценка для завершения составляет 5 секунд.

Некоторое объяснение:

  • pv -lзаставляет pvсчитать по новым строкам вместо байтов
  • pv -s numberговорит, pvчто такое общее количество, чтобы оно могло дать вам оценку.
  • Переадресация logfileв конце предназначена для чистого вывода. В противном случае строка состояния из pvсмешивается с выходом из rm -v. Бонус: у вас будет лог-файл того, что было удалено. Но будьте осторожны, файл станет огромным. Вы также можете перенаправить, /dev/nullесли вам не нужен журнал.

Чтобы получить количество файлов, вы можете использовать эту команду:

$ find dirname | wc -l

Это также может занять много времени, если есть миллиарды файлов. Вы также можете использовать pvздесь, чтобы увидеть, сколько он насчитал

$ find dirname | pv -l | wc -l
278k 0:00:04 [56,8k/s] [     <=>                                              ]
278044

Здесь говорится, что для подсчета 278 тыс. Файлов понадобилось 4 секунды. Точное число в конце ( 278044) является выходным значением wc -l.

Если вы не хотите ждать подсчета, вы можете угадать количество файлов или использовать pvбез оценки:

$ rm -rv dirname | pv -l > logfile

Таким образом, у вас не будет оценки, чтобы закончить, но, по крайней мере, вы увидите, сколько файлов уже удалено. Перенаправьте, /dev/nullесли вам не нужен файл журнала.


придираться:

  • тебе действительно нужно sudo?
  • обычно rm -rдостаточно рекурсивного удаления. нет необходимости rm -f.

5
Хорошее использование pv, при условии, что подсчет миллиардов файлов не слишком дорог ;-). (Это может занять почти столько же времени, сколько rmдолжно быть измерено!)
Стивен Китт

7
@StephenKitt Это то, что действительно раздражает меня (и многих других людей) в файловой утилите Windows: она всегда безошибочно подсчитывает количество и размеры файлов перед удалением, что, если на диске слишком много медленнее, чем процессор, занимает почти пока фактическое удаление!
wizzwizz4

@ wizzwizz4 Действительно! И это еще не все, хотя IIRC - он проверяет, может ли он удалить все, прежде чем что-либо удалять , чтобы увеличить вероятность того, что удаления будут «все или ничего». Много лет назад я написал драйвер файловой системы для Windows, было довольно много странностей, с которыми нам пришлось столкнуться, включая некоторые, связанные с тем, как Проводник удаляет файлы, но я не могу вспомнить детали. (Я помню, что создание папки включает в себя запись и удаление файла в новой папке!)
Стивен Китт

7
@StephenKitt Может быть, я ошибаюсь, но не является ли узкое место, кроме доступа к диску, выводом терминала? Я считаю, pvчто индикатор прогресса обновляется только один раз в секунду, несмотря на его вклад. Таким образом, терминал должен отображать только одну строку вместо тонны каждую секунду. pvнужно только увеличивать счетчик для каждой новой строки, с которой он сталкивается; это должно быть быстрее, чем выполнять перенос строк и вообще не отображать строку в терминале. Думаю бегать сpv таким способом приводит к тому, что удаление файлов происходит быстрее, чем просто rm -rv.
JoL

1
@skywinderrm -rv dirname | pv -l -s $(find dirname | wc -l) > logfile
Lesmana

28

Посмотрите ответ Лесманы , он намного лучше моего - особенно последний pvпример, который займет гораздо больше времени, чем первоначальное молчание, rmесли вы укажете /dev/nullвместо logfile.

Предполагая, что вы rmподдерживаете опцию (возможно, так как вы работаете в Linux), вы можете запустить ее в подробном режиме с помощью -v:

sudo rm -rfv bolands-mills-mhcptz

Как было отмечено рядом комментаторов, это может быть очень медленным из-за количества вывода, генерируемого и отображаемого терминалом. Вместо этого вы можете перенаправить вывод в файл:

sudo rm -rfv bolands-mills-mhcptz > rm-trace.txt

и смотреть размер rm-trace.txt.


5
Это может на самом деле замедлить удаление из-за того, что весь вывод генерируется и выводится на терминал :)
rackandboneman

2
Конечно, это замедлится. Запись миллиардов строк в файл не происходит за нулевое время.
user207421

23

Другой вариант - наблюдать за уменьшением количества файлов в файловой системе. В другом терминале запустите:

watch  df -ih   pathname

Количество используемых инодов будет уменьшаться по мере rm продвижения. (Если файлы в основном не имеют нескольких ссылок, например, если дерево было создано с помощью cp -al). Это отслеживает процесс удаления с точки зрения количества файлов (и каталогов). dfбез -iбудет отслеживать с точки зрения используемого пространства.

Вы также можете запустить iostat -x 4 чтобы увидеть количество операций ввода-вывода в секунду (а также килобайт / с, но это не очень важно для ввода-вывода с чистыми метаданными).


Если вам интересно узнать, над какими файлами rmв данный момент ведется работа, вы можете присоединить straceк нему и посмотреть, как unlink()системные вызовы (и getdents) извергают ваш терминал. напримерsudo strace -p $(pidof rm) . Вы можете ^cотстегнуть ремень, rmне прерывая его.

Я забываю, если rm -rкаталог меняется на дерево, которое он удаляет; если так, вы могли бы посмотреть /proc/<PID>/cwd. Его /proc/<PID>/fdмощь часто каталог Fd открытой, так что вы могли бы смотреть на это , чтобы увидеть , что ваш rmпроцесс в настоящее время рассматривает.


2
df -ihдействительно хороший дешевый способ наблюдать за rmпрогрессом.
Стивен Китт

Кстати, это не работает в BTRFS, где счетчик используемых инодов всегда равен нулю. :( То же самое для FAT32, но у вас, вероятно, нет миллиардов файлов в /bootсистемном разделе EFI.
Питер Кордес

4

Хотя все приведенные выше ответы используют rm, на rmсамом деле удаление большого количества файлов может быть довольно медленным, как я недавно заметил, когда извлечение ~ 100K файлов из архива .tar на самом деле занимало меньше времени, чем их удаление. Хотя это на самом деле не отвечает на вопрос, который вы задали, лучшим решением вашей проблемы может быть использование другого метода удаления ваших файлов, например, одного из ответов на этот вопрос .

Мой личный любимый метод - использовать rsync -a --delete. Я считаю, что этот метод работает достаточно быстро, поэтому его стоит использовать по сравнению с наиболее часто задаваемым ответом на этот вопрос , в котором автор написал C-программу, которую вам нужно будет скомпилировать. (Обратите внимание, что это будет выводить каждый файл, обрабатываемый на стандартный вывод, очень похоже наrm -rv ; это может замедлить процесс на удивительную величину. Если вы не хотите этот вывод, используйте rsync -aq --deleteили перенаправьте вывод в файл.)

Автор этого ответа говорит:

Теперь программа (в моей системе) удалит 1000000 файлов за 43 секунды. Наиболее близкой к этому была программа rsync -a --delete, которая заняла 60 секунд (которая также выполняет удаление по порядку, но не выполняет эффективный поиск в каталоге).

Я обнаружил, что этого достаточно для моих целей. Также потенциально важно из этого ответа, по крайней мере, если вы используете ext4:

В качестве предварительного решения следует удалить поврежденный каталог и переделать его после. Каталоги только увеличиваются в размере и могут работать плохо даже с несколькими файлами внутри из-за размера каталога.


да, я бы ожидал rmи / или find --deleteбыл бы эффективным. Интересный момент об удалении в порядке сортировки, чтобы избежать перебалансировки b-дерева при удалении. Не уверен, насколько это относится к другим файловым системам. XFS также не очень хороша с миллионами файлов в каталоге. ИДК о BTRFS, но у меня сложилось впечатление, что это может быть полезно для такого рода вещей.
Питер Кордес

Разве эта вторая цитата не зависит от типа файловой системы ...
Menasheh

@Menasheh Хорошо, я отредактировал это в своем ответе.
Hitechcomputergeek

3

Одна вещь, которую вы могли бы сделать, это запустить rmпроцесс в фоновом режиме (без вывода, чтобы он не замедлялся), а затем отслеживать его на переднем плане с помощью простой команды (a) :

pax> ( D=/path/to/dir ; rm -rf $D & while true ; do
...>   if [[ -d $D ]] ; then
...>     echo "$(find $D | wc -l) items left"
...>   else
...>     echo "No items left"
...>     break
...>   fi
...>   sleep 5
...> done )

27912 items left
224 items left
No items left

pax> _

find/wcКомбо может быть заменен любым инструментом , способным дать вам единицы , которые вы хотите.


(а) Ну, относительно просто, по сравнению, скажем, с ядерной физикой, гипотезой Римана или с тем, что купить жене на Рождество :-)


0

Некоторое время назад я написал что-то, чтобы напечатать скорость печати строк. Вы можете запустить, rm -rfv | ./counterи он будет печатать строки в секунду / мин. Хотя это и не прямой прогресс, он даст вам некоторую обратную связь о темпах прогресса, может быть,rm забрел в сетевую файловую систему или что-то подобное?

Ссылка на код здесь:

http://www.usenix.org.uk/code/counter-0.01.tar.gz

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.