Слишком много файлов в папке
сколько файлов может содержать папка? У меня 30К папок в папке 1. Каждая из папок имеет 1 файл изображения. Есть ли ограничение на количество файлов в папке может храниться?
Я использую Windows Server 2003, IIS6.
Примечание: предполагая NTFS, так как никто в здравом уме не будет использовать FAT ни для чего другого, кроме USB-накопителей или карт памяти, не говоря уже о сервере (ok, это мысль-это страшно).
Да, есть предел. Хранение большего количества файлов, чем частиц во Вселенной, может оказаться непрактичным. Однако фактический предел значительно меньше.
NTFS имеет максимум 4,294,967,295 (2 32 - 1) файлов на томе. Некоторые из них уже используются самой файловой системой, и папка также должна считаться файлами.
30,000 не так уж много файлов. Но Microsoft рекомендует что ты выключить автоматическое создание DOS-совместимых коротких имен, если вы двигаетесь мимо 300,000, как найти уникальное короткое имя становится трудно, то.
там нет практических ограничений на объединенные размеры всех файлов в папке, хотя могут быть ограничения на количество файлов в папке. Что еще более важно, существуют ограничения на размер отдельных файлов, которые зависят от того, какую файловую систему вы используете на жестком диске. ("Файловая система" - это не что иное, как спецификация того, как именно файлы хранятся на диске.)
разберем по файловой системе:
•жир aka FAT16
жир, для таблицы распределения файлов, является преемником оригинальной файловой системы FAT12, поставляемой с MS-DOS много, много лет назад.
Maximum максимальный размер диска: 4 гигабайта
◦максимальный размер файла: 4 ГБ
◦максимальное количество файлов на диске: 65,517
Maximum максимальное количество файлов в одной папке: 512 (если я правильно помню, корневая папка "/" имела нижний предел 128).
•FAT32
" там нет практических лимит на общий размер всех файлов в папке, хотя там может быть ограничения на количество файлов в папке."FAT32 был введен для преодоления некоторых ограничений FAT16.
◦максимальный размер диска: 2 ТБ
◦максимальный размер файла: 4 ГБ
◦максимальное количество файлов на диске: 268,435,437
◦максимальное количество файлов в одной папке: 65 534
•NTFS
NTFS, или " новая технология Файловая система", введенная в Windows NT, является полностью переработанной файловой системой.
◦максимальный размер диска: 256 терабайт
◦максимальный размер файла: 256 терабайт
◦максимальное количество файлов на диске: 4,294,967,295
◦максимальное число файлов в одной папке: 4,294,967,295
обратите внимание, что когда я говорю "диск" выше, я действительно говорю о "логических" дисках, не обязательно физических. Никто не делает 256 терабайт диск, но с помощью NTFS массив дисков можно рассматривать как один логический диск. Предположительно, если у вас их достаточно, вы можете построить огромный логический диск.
Также обратите внимание, что ограничение NTFS в 256 терабайт вполне может быть просто ограничение реализации - я читал, что формат NTFS может поддерживать диски до 16 эксабайт (16 раз 1,152,921,504,606,846,976 байт).
Скорей всего, матерым системным администраторам статья будет не очень интересна. В первую очередь она ориентирована на новичков, а также на людей, которые столкнулись с подобной проблемой — необходимостью удалить огромное количество файлов из одной папки в ОС Linux (Debian в моем случае), а также с закончившимся местом на диске, когда df -h выдает что почти 30% свободно.
Начало
Ничто не предвещало беды.
Сервер с сайтом работал без никаких проблем уже больше года (uptime почти 500 дней), не было никаких проблем, и я с чистой душой спокойно ушел в отпуск.
В первый же день отпуска мне звонят с жалобой — сайт недоступен. MySQL падает с ошибкой Error 28 «No space left on device».
Казалось бы, проблема банальна — кончилось место на диске. Правда, df -h показывает, что на диске имеется вполне достаточное количество свободного места, ну да я же в отпуске, разбираться лень — посоветовал им поискать на диске ненужные файлы (старые бекапы и т.д.) и их удалить. Удалили, вроде все заработало.
Прошла пара часов и проблема вернулась. Странно — свободное место на жестком диске за это время практически не уменьшилось. После беглого гугления обнаружился топик на serverfault, в котором говорится, что проблема может возникнуть также из-за того, что кончилось не место на диске, а айноды!
Ввожу в консоль df -i — и оказывается действительно, айноды у меня закончились.
Проблема
Начал искать, где же у меня находится столько файлов на жестком диске, что они сожрали все айноды (а айнодов у меня на 500-гигабайтном жестком диске больше 30 миллионов).
И нашел — оказалось, проблема была в папке с сессиями php.
Видимо, по какой-то причине сломался механизм автоочистки этой папки, что привело к тому, что в ней скопилось огромное количество файлов. Насколько огромное — сказать сложно, потому что никакие стандартные команды линукс, такие, как ls, find, rm и т.д. — с этой папкой не работают. Просто виснут, заодно подвешивая весь сервер. Могу только сказать, что сам файл директории стал весит около гигабайта, а также что файлов там точно более полумиллиона, потому что столько я оттуда уже удалил.
Решение
Решение очевидное — надо удалить все эти файлы сессий. При этом желательно, чтобы сервер продолжал работать в штатном режиме. Для начала я переименовал папку сессий, в которой лежит куча файлов, а вместо нее создал пустую — чтобы спокойно из старой (переименованной) удалять все файлы, и чтобы это не мешало созданию новых файлов сессий.
Также в крон добавил автоматическое удаление файлов сессий старше одного часа, чтобы проблема больше не повторилась.
И перешел к основной проблеме — очистке жесткого диска.
Попробовал решение «в лоб»:
Сервер повис, ничего не удалилось
Попробовал известный способ для удаления большого числа файлов
Ничего, сервер виснет, файлы не удаляются.
А теперь что самое интересное — файловый менеджер mc достаточно успешно справлялся с задачей удаления этих файлов! То есть, когда запускаешь удаление папки — файлы удаляются, mc не виснет. Удаление идет со скоростью примерно 5 000 файлов в минуту, правда при этом создается огромная нагрузка на жесткий диск, что приводит к неработоспособности сервера.
А хотелось бы, чтобы эти файлы постепенно удалялись в фоновом режиме, и не мешали нормальной работе сайта.
Собственно, решение опять нашлось в гугле — Olark делится способом, как он отобразил список из 8 миллионов файлов в 1 папке, используя системный вызов getdents
Здесь находится документация по функции getdents, а также пример кода, который ее использует.
Правда, этот пример мне не совсем подошел — даже если ставить большой размер буфера, как советует Olark в своем блоге, все равно сервер виснет при попытке прочитать всю папку разом.
Опытным путем подобрал размер буфера в 30 килобайт, который позволяет считать около 550 названий файлов из директории, при этом не подвешивая сервер и не создавая излишней нагрузки на диск. А также немного переписал код примера, чтобы вместо отображения имени файла он его удалял.
В итоге у меня получился такой код:
Код компиллируется обычным gcc
И просто запускается из командной строки:
Получившийся файл я поставил в крон и теперь у меня удаляется по 547 файлов в минуту, при этом нагрузка на сервер в пределах нормы — и я надеюсь, в течение недели-другой все файлы все-таки удалятся.
Как известно в одной папке не стоит хранить большое количество файлов т.к. очень быстро может произойти сбой в системе или попросту файлы будут очень медленно считываться.
Для решения этой задачи многие программисты берут md5 имени файла f789f789abc898d6892df98d09a8f8, после чего разбивают имя примерно таким образом:
/f7/89/f789abc898d6892df98d09a8f8.jpg
Математика тут очень проста — один символ это 16 вариантов.
Таким образом 2 символа это уже 16*16=256 вариантов.
В нашем случае у нас 2 вложенности по 2 символа, таким образом максимальное количество папок будет 256*256=65536 папок.
Если нам потребуется сохранить 1000000 файлов то число файлов в каждой папке не превысит 1000000/65536=15 файлов.
Да, вариант прост, но что если нам требуется не только хорошо сохранять файлы, но и еще быстро их находить?
Например у нас социальная сеть и мы хотим для каждого пользователя создать отдельную папку с номером его id и хранить в ней файлы которые в свою очередь тоже имеют свой id.
И для нас важно не только сохранить файл но и быстро найти где он лежит по его id.
Для решения этой задачи я написал класс, который позволяет сохранять на сервере большое количество файлов или папок в древовидной структуре папок.
Вот какую структуру создает класс:
Чтобы посчитать максимально число файлов которое уместится в этой структуре нужно возвести максимальное количество файлов в папке в степень количества ветвей плюс один.
На изображении мы видим 2 ветви и по 3 файла в каждой папке.
Таким образом 3 нужно возвести в степень 2+1 = 3*3*3=27 файлов.
Для сохранения не более 1000000 файлов в такой структуре нам хватит 2 ветви по 100 файлов в каждой папке (100*100*100).
В класс нужно передать массив параметров — путь к папке где будет строиться дерево, максимальное число файлов в папке, число ветвей, либо можно применить паттерн (параметр pattern) максимального числа файлов, который уже был заранее просчитан — bigint, int, mediumint, smallint:
Для варианта социальной сети описанной выше, требуется 2 раза использовать класс: вначале для построения дерева папок, потом для построения в каждой папке дерева для файлов.
Так же обращаю ваше внимание, что в этом посте я опустил (а не не знал) тему «Максимально допустимое количество файлов на жестком диске».
Феерическая расстановка точек над 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, не увеличивая размер файла образа. Но, с другой стороны, стандартные настройки — ближе к реальным условиям.
Создаем множество пустых файлов (будет работать несколько часов)
Кстати, если в начале файлы создавались достаточно быстро, то последующие добавлялись всё медленнее и медленнее, появлялись рандомные паузы, росло использование памяти ядром. Так что хранение большого числа файлов в плоской директории само по себе плохая идея.
Проверяем, что все айноды на ФС исчерпаны.
Размер файла директории ~360Мб
Теперь попробуем удалить эту директорию со всем её содержимым различными способами.
Тесты
После каждого теста сбрасываем кеш файловой системы
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 говорит, что не нужно сортировать список файлов.
Создает такую иерархию процессов:
Удаление через 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 — вполне нормально, если не накапливать результаты в памяти, а удалять файлы сразу.
в основном, у меня есть альбом музыки, и я хочу, чтобы удалить имя автора из всех mp3-файлов вместо того, чтобы вручную сделать это сам. Есть ли функция в Windows 7 Ultimate, которая может сделать это для меня?
вы также можете попробовать использовать PowerShell, мощный инструмент командной строки Windows. Вы выполните следующую команду:
Полная Команда:
get-childitem *.mp3
Здесь перечислены все файлы, имена которых заканчиваются на .mp3 . Затем они передаются в следующую команду с помощью | оператора.
foreach < rename-item $_ $_.Name.Replace("Radiohead -", "") >
Это заменяет все экземпляры Radiohead - ни с чем, обозначается "" , эффективно стирая слово из всех файлов в каталоге.
вы также можете изменить get-childitem *.mp3 до get-childitem - это переименует все файлы в каталоге, а не только файлы, имена которых заканчиваются на .mp3 .
забудьте о сложных скриптах для этого.
rename - очень старая и никогда должным образом не выполняемая команда. Если вы не используете его правильно, результат может вас удивить.
например, чтобы удалить префикс abcd С abcd1.txt , abcd2.txt , abcd3.txt etc. для того, чтобы получить 1.txt , 2.txt , 3.txt просто использовать
вам нужно то же количество / как количество исходных символов, которые вы хотели бы удалить.
Do заключите оба аргумента в двойные кавычки.
Это может сработать.
создать пакетный файл следующим образом:
попробуйте это программное обеспечение
Так как вы имеете дело с музыкальными файлами, забудьте о пакетном файле и утилит для переименования файлов. Используйте специальную программу, например Mp3tag, который является абсолютной необходимостью, если вы действительно в организации вашей музыки.
основные возможности
Пакетное Редактирование Тегов Запись Тэгов Id3v1.1, ID3v2 тэгов.3, ID3v2 тэгов.4, в формате mp4 и WMA, APEv2 Теги и Vorbis комментарии для нескольких файлов сразу.
поддержка Обложка скачать и добавить обложки альбомов в файлы и сделать вашу библиотеку еще более блестящей.
импорт из Amazon, discogs, freedb, MusicBrainz сохранить ввод и импорт теги из онлайн баз данных, такие как Амазонки, биография, фотографии, с freedb, в MusicBrainz, с лишним.
заменить символы или слова замена строк в тегах и именах файлов (с поддержкой регулярных Формы самовыражения.)
Создание Плейлистов автоматически создание списков воспроизведения и управление ими автоматически во время редактирования.
переименование файлов из тегов переименование файлов на основе информации тегов и импорт тегов из имен файлов.
экспорт в HTML, RTF, CSV генерировать хорошие отчеты и списки ваших коллекции на основе пользовательских шаблоны.
Полная Поддержка Unicode пользовательский интерфейс и маркировать полно Совместимых Unicode.
кроме этих главным образом характеристик Mp3tag предлагает множество других функций и характеристики колебаясь от пакетный экспорт встроенных обложек альбомов, поддержка тегов для iTunes как тип носителя или настройки телешоу, к объединению нескольких действий в группы, которые могут быть применены с один щелчок мыши.
ReNamer можете это сделать. В ReNamer просто добавьте правило 'remove' (правило 'delete' также будет работать):
а затем перетащите файлы или папку, содержащую файлы, которые вы хотите переименовать в его окно (или используйте кнопки "Добавить файлы / папки"), затем проверьте предварительный просмотр и после проверки нажмите "переименовать":
Я просто хочу добавить мое любимое: Переименовать Master
эта утилита будет добавлять, удалять или заменять части имени файла с легкостью, а также поддерживает переименование через свойства файла, MP3 теги, jpeg jfif и EXIF теги, видео Теги и текстовые файлы. Пакетное переименование, простое в использовании, но все еще очень мощное.
особенности
у меня было соответствующее требование.
внимание:
Сделайте резервную копию папки, в которой вы пробуете следующие команды.
Пример 1:
внимание: эта команда перезаписывает часть существующего имени файла
если в каталоге всего два файла:
и если вы запустите:
затем файлы изменяются to:
Пример 2:
внимание: эта команда удаляет часть существующего имени файла
Читайте также: