Comments 103
мгновенное создание 200G
dd if=/dev/zero of=./disk-image bs=1M count=0 seek=200G
dd if=/dev/zero of=./disk-image bs=1M count=0 seek=200G
Только bs дожен быть просто 1, без суффикса M, иначе это создание файла размером в 200000 ПБ
dd if=/dev/zero of=./disk-image bs=1 count=0 seek=200G
dd if=/dev/zero of=./disk-image bs=1 count=0 seek=200G
Точно, так работает.
dlinyj@dlinyj-System:~/tmp/test$ dd if=/dev/zero of=./disk-image bs=1 count=0 seek=200M
0+0 записей считано
0+0 записей написано
скопировано 0 байт (0 B), 2,2231e-05 c, 0,0 kB/c
dlinyj@dlinyj-System:~/tmp/test$ ls -la
итого 8
drwxrwxr-x 2 dlinyj dlinyj 4096 нояб. 7 14:24.
drwxrwxr-x 15 dlinyj dlinyj 4096 нояб. 7 14:24…
-rw-rw-r-- 1 dlinyj dlinyj 209715200 нояб. 7 14:26 disk-image
dlinyj@dlinyj-System:~/tmp/test$
dlinyj@dlinyj-System:~/tmp/test$ dd if=/dev/zero of=./disk-image bs=1 count=0 seek=200M
0+0 записей считано
0+0 записей написано
скопировано 0 байт (0 B), 2,2231e-05 c, 0,0 kB/c
dlinyj@dlinyj-System:~/tmp/test$ ls -la
итого 8
drwxrwxr-x 2 dlinyj dlinyj 4096 нояб. 7 14:24.
drwxrwxr-x 15 dlinyj dlinyj 4096 нояб. 7 14:24…
-rw-rw-r-- 1 dlinyj dlinyj 209715200 нояб. 7 14:26 disk-image
dlinyj@dlinyj-System:~/tmp/test$
Да, это работает. Спасибо!
Для создания swap файла такой метод не прокатит.
Ubuntu 12.04, в связи с недостатком места для размещения 200 гигабайт, решил обойтись 200 мегабайтами.
dlinyj@dlinyj-System:~/tmp/test$ dd if=/dev/zero of=./disk-image bs=1M count=0 seek=200M
dd: не удалось выполнить отсечение на 219902325555200 байт в выходном файле «./disk-image»: Файл слишком велик
dlinyj@dlinyj-System:~/tmp/test$ ls -la
итого 8
drwxrwxr-x 2 dlinyj dlinyj 4096 нояб. 7 14:24.
drwxrwxr-x 15 dlinyj dlinyj 4096 нояб. 7 14:24…
-rw-rw-r-- 1 dlinyj dlinyj 0 нояб. 7 14:24 disk-image
dlinyj@dlinyj-System:~/tmp/test$
dlinyj@dlinyj-System:~/tmp/test$ dd if=/dev/zero of=./disk-image bs=1M count=0 seek=200M
dd: не удалось выполнить отсечение на 219902325555200 байт в выходном файле «./disk-image»: Файл слишком велик
dlinyj@dlinyj-System:~/tmp/test$ ls -la
итого 8
drwxrwxr-x 2 dlinyj dlinyj 4096 нояб. 7 14:24.
drwxrwxr-x 15 dlinyj dlinyj 4096 нояб. 7 14:24…
-rw-rw-r-- 1 dlinyj dlinyj 0 нояб. 7 14:24 disk-image
dlinyj@dlinyj-System:~/tmp/test$
Я, кстати, понял чем отличается файл, созданный с помощью seek от файла честно заполненного нулями…
Т.е. файл хоть и весит 600Гб, но места на диске не занимает. Возможно это какая-то оптимизация файловой системы, не знаю.
$ ls -lh disk* -rw-rw-r-- 1 seriy seriy 600G нояб. 7 14:29 disk-image -rw-rw-r-- 1 seriy seriy 600G нояб. 7 14:33 disk-image2 -rw-rw-r-- 1 seriy seriy 600G нояб. 7 14:33 disk-image3 -rw-rw-r-- 1 seriy seriy 600G нояб. 7 14:33 disk-image4 $ df -h | grep /home /dev/sda5 1,8T 822G 900G 48% /home
Т.е. файл хоть и весит 600Гб, но места на диске не занимает. Возможно это какая-то оптимизация файловой системы, не знаю.
Это обычный sparse-файл
Да, это sparse file что, кстати, и отражено в его названии в статье ;-)
P. S. Почему коментарий можно редактировать, но нельзя удалить? Дубликат же получился :-(
P. S. Почему коментарий можно редактировать, но нельзя удалить? Дубликат же получился :-(
truncate -s 200G disk-image
Использую
find. | xargs rm
Пока не подводило.
find. | xargs rm
Пока не подводило.
А сделайте тоже самое на reiserfs 3
Между миллионом и 13 млн файлов существенная разница! Вы не смотрели сколько RAM занимает find при этом?
Мой опыт показывает, что find всегда строит в памяти полный список файлов в директории прежде чем начать проводить с ними какие-то операции.
Может расскажете как вы пришли к такому решению
Мой опыт показывает, что find всегда строит в памяти полный список файлов в директории прежде чем начать проводить с ними какие-то операции.
Может расскажете как вы пришли к такому решению
find не всегда строит, а смотрит на количество оставшейся памяти и пытается балансировать между минимизацией вызовов readdir и потреблением памяти. Попробуйте запустить его под ulimit — хорошо иллюстрирует.
Подскажите какие ulimit задавать?
попробовал
с
попробовал
ulimit -m $((1024 * 50))
— не помогло. Так же набирает по 500 Мбс
ulimit -v $((1024 * 50))
после 50Мб молча падаетЕсли речь о GNU'шном find, то он при своей работе заводит списки структур
Дальше, если новый объем пытается выделиться или реаллоцироваться через
С точки зрения использования ulimit:
savedir_dirinfo
, которые пытается инкрементально порождать на каждую директорию, начиная выделение с xmalloc
на 16 байт, а затем растягивая получившуюся систему буферов с помощью extendbuf
, которая в свою очередь выбирает размер нового буфера тупым нахождением округления сверху (в общем, практически чуть ли не первая реализация из классической книжки Кнута): while (newsize < wanted)
{
if (2 * newsize < newsize)
xalloc_die ();
newsize *= 2;
}
return newsize;
Дальше, если новый объем пытается выделиться или реаллоцироваться через
xmalloc
/ xrealloc
и если не получится это сделать, то find отнюдь не впадает в панику и не считает это критической ошибкой, а, напротив, считает, что все, памяти уже достаточно и возвращается к предыдущему объему — и вот тут-то и должен сработать механизм дампа всего накопившегося, если это возможно (разумеется, нужно отсутствие флага SavedirSort, иначе будет вызван qsort и будет делаться сортировка вывода, что в данном случае смерти подобно).С точки зрения использования ulimit:
-m
в современных Linux вообще смысла не имеет, см. RLIMIT_RSS, можно попробовать -d
(но тогда и смотреть надо на data segment и учесть, что там бывает только софт-лимит), ну и по идее должен работать -v
— там просто проблема в том, что он еще и стек лимитирует и при исчерпании стека будет предсказуемо SIGSEGV — возможно, вы столкнулись именно с этой ситуацией. Можно попробовать лимитировать -v
, но сделать -s
побольше. Ну или вообще не трогать ulimit, а лимитировать через cgroups.Попробовал ограничить через cgroups
При отключенном swap процесс прибивается по достижении 700Мб, если swap включен — уходит в swap.
Но так ничего и не удаляет.
Если не поленюсь — запущу под виртуальной машиной.
sudo cgcreate -a $USER -g memory:tst
echo 700000000 > /sys/fs/cgroup/memory/tst/memory.limit_in_bytes
sudo cgexec -g memory:tst find /mnt/ext4/test_dir/ -delete
При отключенном swap процесс прибивается по достижении 700Мб, если swap включен — уходит в swap.
Но так ничего и не удаляет.
Если не поленюсь — запущу под виртуальной машиной.
Можете уточнить, что значит «прибивается»? Это все-таки SIGSEGV или oomkiller, скажем, у вас как-то агрессивно срабатывает?
Судя по syslog это oom killer
Nov 10 22:08:39 seriy-desktop kernel: [ 1772.927181] find invoked oom-killer: gfp_mask=0xd0, order=0, oom_adj=0, oom_score_adj=0 Nov 10 22:08:39 seriy-desktop kernel: [ 1772.927186] find cpuset=/ mems_allowed=0 .......... Nov 10 22:08:39 seriy-desktop kernel: [ 1772.927269] Task in /tst killed as a result of limit of /tst Nov 10 22:08:39 seriy-desktop kernel: [ 1772.927272] memory: usage 292972kB, limit 292972kB, failcnt 55186 Nov 10 22:08:39 seriy-desktop kernel: [ 1772.927274] memory+swap: usage 292972kB, limit 9007199254740991kB, failcnt 0 ........... Nov 10 22:08:39 seriy-desktop kernel: [ 1772.949829] [ pid ] uid tgid total_vm rss cpu oom_adj oom_score_adj name Nov 10 22:08:39 seriy-desktop kernel: [ 1772.949893] [ 5616] 0 5616 77136 73379 2 0 0 find Nov 10 22:08:39 seriy-desktop kernel: [ 1772.949895] Memory cgroup out of memory: Kill process 5616 (find) score 974 or sacrifice child Nov 10 22:08:39 seriy-desktop kernel: [ 1772.949898] Killed process 5616 (find) total-vm:308544kB, anon-rss:292736kB, file-rss:780kB
Ну, тогда как бы эксперимента не получается: oom killer убивает find еще до того, как он успеет узнать, что памяти ему не дали и поумерить свои аппетиты. Попробуйте выключить oom_killer для этой cgroup, что-то типа:
echo 1 >/sys/fs/cgroup/memory/tst/oom_control
echo 1 >/sys/fs/cgroup/memory/tst/memory.oom_control
Теперь дорастает до 300Мб и засыпает на __mem_cgroup_try_charge
.Ладно, по-моему отклонились от темы.
Нет причин вам не верить. Но, похоже, find не успокаивается пока не займёт всю доступную память, включая swap. Что есть не самое удачное поведение.
Ну, мне на самом деле самому интересно, что на современных системах получается. Насколько я понимаю, поведения вида «займем всю выданную память» с некоей авторегуляцией процесса занятия со стороны программы, на современных системах (и с точки зрения аппаратного развития — всякие там SMP, multi core и т.д., и с точки зрения программного — OOM killers, cgroups, поломанные setrlimit), мягко говоря, работает плохо.
Что, в свою очередь, приводит к невеселым мыслям о том, что в целом единственный на сегодня жизнеспособный путь авторегуляции занимаемой памяти — это когда есть какая-то виртуальная машина (типа той же jvm), где на контекст этой виртуальной машины задается какое-то общее ограничение памяти и в нем и происходит жизнь.
А с C-based все получается именно что вот так грустно: либо непортабельно, либо не особенно работоспособно, либо и то, и другое…
Что, в свою очередь, приводит к невеселым мыслям о том, что в целом единственный на сегодня жизнеспособный путь авторегуляции занимаемой памяти — это когда есть какая-то виртуальная машина (типа той же jvm), где на контекст этой виртуальной машины задается какое-то общее ограничение памяти и в нем и происходит жизнь.
А с C-based все получается именно что вот так грустно: либо непортабельно, либо не особенно работоспособно, либо и то, и другое…
А если так?
find /mnt/test_dir/ -delete
find -type f не всегда помогает, иногда приходится делать find -not -type d
>>>К сожалению, не нашел в Python функции для итеративного чтения директории, чему крайне удивлён; os.listdir() и os.walk() читают директорию целиком
Судя по документации, os.listdir() должна возвращать список сразу, в то время как os.walk() как раз отдаёт результат постепенно.
os.listdir(path) — Return a list containing the names of the entries in the directory given by path.
os.walk(top, topdown=True, onerror=None, followlinks=False) — Generate the file names in a directory tree by walking the tree either top-down or bottom-up. For each directory in the tree rooted at directory top (including top itself), it yields a 3-tuple (dirpath, dirnames, filenames).
Судя по документации, os.listdir() должна возвращать список сразу, в то время как os.walk() как раз отдаёт результат постепенно.
os.listdir(path) — Return a list containing the names of the entries in the directory given by path.
os.walk(top, topdown=True, onerror=None, followlinks=False) — Generate the file names in a directory tree by walking the tree either top-down or bottom-up. For each directory in the tree rooted at directory top (including top itself), it yields a 3-tuple (dirpath, dirnames, filenames).
Вот прям сейчас специально проверил
Жрет память, ничего не печатает
import os
for l in os.walk("/mnt/test_dir/"):
print l
Жрет память, ничего не печатает
А glob.iglob не помогает?
Сам себе отвечу. Судя по всему glob использует тот же listdir. Так что не поможет.
Вы не выделили жирным.
it yields a 3-tuple (dirpath, dirnames, filenames).
filenames is a list of the names of the non-directory files in dirpath.
it yields a 3-tuple (dirpath, dirnames, filenames).
filenames is a list of the names of the non-directory files in dirpath.
В Linux никак нельзя удалить файлы из папки, в Linux нет папок, как и мамок, как и дедок.
В Linux есть директории.
В Linux есть директории.
Нет никаких директорий, вам наврали, есть иноды с различными аттрибутами )
… и есть там только железяка, с куском рандомно намагниченных точек, вращающаяся в пространстве вокруг своей оси. И смотрите вы сейчас не на сайт, и даже не на браузер, а на тонкий слой жидких кристаллов, меняющих свою поляризацию в зависимости от электрических импульсов…
я гляжу виндузятник позвал дружков неудачников за указание ошибки.
неплохо-неплохо.
вот только от туповатых виндузятников директория папкой не станет.
неплохо-неплохо.
вот только от туповатых виндузятников директория папкой не станет.
Заголовок статьи я взял от первоначальной статьи habrahabr.ru/post/152193/
В тексте статьи везде использую «директория».
В тексте статьи везде использую «директория».
Да хоть откуда берите. Сразу палиться виндузятник. Папка — пьяный бред переводчиков какой-то из их недоос.
о, а не подскажете, как трезвый линуксоид в здравом уме перевел бы слово «folder»?
Неграмотный фанатик тоже сразу «палитЬся».
Папка — название виджета графического интерфейса, которым традиционно визуально представляют директории. Потому, что на изображении виджета собственно нарисована папка для бумаг. Это не переводчики придумали, а дизайнеры. Прижилось.
А ещё в Фигурнове было слово «каталог».
Папка — название виджета графического интерфейса, которым традиционно визуально представляют директории. Потому, что на изображении виджета собственно нарисована папка для бумаг. Это не переводчики придумали, а дизайнеры. Прижилось.
А ещё в Фигурнове было слово «каталог».
«директории», ежливчо, это ещё более пьяный бред причом даже не переводчика.
Правильное, русское, слово — каталоги.
Но всем пофик.
Правильное, русское, слово — каталоги.
Но всем пофик.
Спасибо хорошая статья ))
Да прекратите уже размусоливать…
100 раз уже и на опеннете писалось, и в предыдущем топике я об этом упоминал.
rm -rfd /path
100 раз уже и на опеннете писалось, и в предыдущем топике я об этом упоминал.
Я пробовал. У меня ругнулся что нет опции
Кстати, судя по ману (
"-d"
.$ rm --version
rm (GNU coreutils) 8.13
Кстати, судя по ману (
man 2 unlink
), unlink не удаляет директорииERRORS .... EISDIR pathname refers to a directory. (This is the non-POSIX value returned by Linux since 2.1.132.)
Не знаю, у меня вот rm (GNU coreutils) 7.4
И хоть ключика нет в --help, он есть и работает ровно так, как я того ожидаю.
Прочитал про него давным давно на LOR.
И хоть ключика нет в --help, он есть и работает ровно так, как я того ожидаю.
Прочитал про него давным давно на LOR.
А исходники читать не пробовали? Нет там такой опции
Когда ее там нет, я вижу ошибку
rm: invalid option -- 'd'
while ((c = getopt_long (argc, argv, "dfirvIR", long_opts, NULL)) != -1)
{
switch (c)
{
case 'd':
/* Ignore this option, for backward compatibility with
coreutils 5.92. FIXME: Some time after 2005, change this
to report an error (or perhaps behave like FreeBSD does)
instead of ignoring the option. */
break;
Собственно, опция-то есть! Нет реализации :)
Ну, я последний раз пользовался ею в дебиане 4-м, сейчас вся мелочь в memcache живет.
Тогда оно реально сработало и сильно облегчило мне жизнь.
Тогда оно реально сработало и сильно облегчило мне жизнь.
>Some time after 2005, change this…
Ну, надо подождать до 2005-го, чего не ясно?
Ну, надо подождать до 2005-го, чего не ясно?
>… to report an error
Это исходник версии 7.4 (2006 год). В текущих версиях этого фрагмента нет, и rm ругается на опцию -d.
Вы что сказать то хотели?
Это исходник версии 7.4 (2006 год). В текущих версиях этого фрагмента нет, и rm ругается на опцию -d.
Вы что сказать то хотели?
А в мане от 8.5 (Debian 6.0.6) кстати есть.
Но заметьте, советуют проверить диск :)
-d, --directory
Удалять каталоги с помощью системного вызова unlink(2) вместо rmdir(2), и не требовать, чтобы каталог был пуст перед его разлинковкой. Работает только если у вас есть соответствующие привилегии. Поскольку разлинковка (разрыв связи) каталога приводит к тому, что все файлы в удаленном каталоге теряют ссылочную целостность, то будет благоразумно после этой операции проверить файловую систему командой fsck(8).
Но заметьте, советуют проверить диск :)
Однако у меня не ругается (в мане нет опции). Тоже GNU coreutils 7.4
Вот можно почитать: www.opennet.ru/man.shtml?topic=rm&category=1&russian=0
Вот можно почитать: www.opennet.ru/man.shtml?topic=rm&category=1&russian=0
Да, залез в исходники, нет кода :( Заколдовали… БСД рулит, там есть :)
Ключ -d есть во FreeBSD
$ man rm
RM(1) FreeBSD General Commands Manual RM(1)
NAME
rm, unlink -- remove directory entries
SYNOPSIS
rm [-f | -i] [-dIPRrvW] file ...
unlink file
DESCRIPTION
The rm utility attempts to remove the non-directory type files specified
on the command line. If the permissions of the file do not permit writ-
ing, and the standard input device is a terminal, the user is prompted
(on the standard error output) for confirmation.
The options are as follows:
-d Attempt to remove directories as well as other types of files.
$ rm -rfd 4444/
rm: invalid option — 'd'
Try `rm --help' for more information.
$ cat /etc/lsb-release |grep DISTRIB_DESCRIPTION
DISTRIB_DESCRIPTION=«Ubuntu 12.04.1 LTS»
$ uname -a
Linux relgames 3.2.0-32-generic #51-Ubuntu SMP Wed Sep 26 21:33:09 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
rm: invalid option — 'd'
Try `rm --help' for more information.
$ cat /etc/lsb-release |grep DISTRIB_DESCRIPTION
DISTRIB_DESCRIPTION=«Ubuntu 12.04.1 LTS»
$ uname -a
Linux relgames 3.2.0-32-generic #51-Ubuntu SMP Wed Sep 26 21:33:09 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
Кстати, интересно вот что… После того как мы сделали
А fsck после этого не будет ли работать дольше чем
А после fsck не появятся ли все эти файлы в
В общем, нужно проверять.
rm -d
у нас все айноды освободятся?А fsck после этого не будет ли работать дольше чем
rm -rf
?А после fsck не появятся ли все эти файлы в
lost+found
?В общем, нужно проверять.
А вот интересно, в unix-е каталог, это тоже файл. Нужно попытаться этот файл каким-то образом обнулить.
>dir — не прокатит, конечно :) Но может через системный вызов какой?
Хотя, даже если это и удастся сделать, после этого, наверняка, придется использовать fsck и чистить lost+found.
>dir — не прокатит, конечно :) Но может через системный вызов какой?
Хотя, даже если это и удастся сделать, после этого, наверняка, придется использовать fsck и чистить lost+found.
На какой файловой системе тестировали?
У меня была проблема с ext3.
Собственно, мое решение с getends было (для меня) хорошо тем, что не нагружало ни диск, ни память, ни что-то другое, т.е. сервер продолжал работать без перебоев, при этом файлы в фоне удалялись.
Способы с rm тоже работали (удаляли файлы) но на время работы делали сервер неработоспособным из-за того, что удаление забивало полностью диск и другие процессы не могли нормально с него читать
У меня была проблема с ext3.
Собственно, мое решение с getends было (для меня) хорошо тем, что не нагружало ни диск, ни память, ни что-то другое, т.е. сервер продолжал работать без перебоев, при этом файлы в фоне удалялись.
Способы с rm тоже работали (удаляли файлы) но на время работы делали сервер неработоспособным из-за того, что удаление забивало полностью диск и другие процессы не могли нормально с него читать
Года три назад была ситуация, когда файлы сессий создавались, но не удалялись :D, в итоге на диске в 1ТБ было занято около 75% инодов. Сколько там было файлов не известно. Удаление стандартными средствами не давало результатов, либо было слишком медленным.
Ситуацию спас find, с поиском по инодам.
Ситуацию спас find, с поиском по инодам.
find . -inum 0000000 -exec rm -i {} \
Для того чтоб айнодов было больше можно уменьшить размер блока в ext4:
В этом случае минимальный размер папки будет не 4Kb а 2Kb а айнодов будет в 2 раза больше
или
В этом случае минимальный размер папки будет 1Kb а айнодов будет в 4 раза больше
mkfs -t ext4 -b 2048
В этом случае минимальный размер папки будет не 4Kb а 2Kb а айнодов будет в 2 раза больше
или
mkfs -t ext4 -b 1024
В этом случае минимальный размер папки будет 1Kb а айнодов будет в 4 раза больше
Было такое очень давно (тоже с какими-то сессиями). Кажется помогло что-то типа
rm 00* потом rm 01* потом… rm ff*
ничего лучше на тот момент не придумал.
rm 00* потом rm 01* потом… rm ff*
ничего лучше на тот момент не придумал.
Для большого кол-ва элементов в exec'е find'а стоит использовать + вместо;
Если верить ману, ведет себя схоже с xargs.
find /mnt/test_dir/ -type f -exec rm -v {} \+
Если верить ману, ведет себя схоже с xargs.
А как же Argument list too long в rm?
Возможно ли, что поведение rm зависит от ОС/ядра?
Возможно ли, что поведение rm зависит от ОС/ядра?
Я в свое время использовал простейщий однострочник
for i in /mnt/test_dir/*; do rm -f $i; done
Конечно, не самый оптимальный вариант, т.к. удаляет по одному файлу, но проблема стояла остро и решить ее надо было прямо сейчас.
ФС была ext3, файлов не 5 миллионов, конечно, но не меньше 1 миллиона.
for i in /mnt/test_dir/*; do rm -f $i; done
Конечно, не самый оптимальный вариант, т.к. удаляет по одному файлу, но проблема стояла остро и решить ее надо было прямо сейчас.
ФС была ext3, файлов не 5 миллионов, конечно, но не меньше 1 миллиона.
А когда отменили ARG_MAX?
смысл xargs не запускаться по 100 аргументов (-n100), а запускаться с столькими аргументами, сколько влезет в ARG_MAX.
вам можно было бы миллион, например, поставить, если нет ARG_MAX
смысл xargs не запускаться по 100 аргументов (-n100), а запускаться с столькими аргументами, сколько влезет в ARG_MAX.
вам можно было бы миллион, например, поставить, если нет ARG_MAX
find /var/lib/php/session -depth -mindepth 1 -maxdepth 1 -type f -ctime +ХХХ -execdir fuser -s {} 2>/dev/null \; -delete
До сих пор не могу понять этот шаман-код Плеска.
Заменил в коде
Вызываю так, что позволяет рекурсивно обходить каталоги и зачищать их
chdir("/mnt/test_dir"); на chdir(argv[1]);
Вызываю так, что позволяет рекурсивно обходить каталоги и зачищать их
find /backup/daily.5/ -type d -printf "Cleaning: %p\n" -exec /usr/bin/cleandir {} \;
rm -r /mnt/test_dir/
извините, но у вас в заголовке «как удалить файлы ИЗ папки», а приводите команду которая удаляет не только файлы но и папку.
ps я вижу, что статья 2012, а на дворе 2019
Sign up to leave a comment.
Так как же удалить миллионы файлов из одной папки?