Как исправить ошибки прерывистого «Нет места на устройстве» во время mv, когда на устройстве достаточно места?

21
  • Ubuntu 14.04 на рабочий стол
  • Исходный диск: / dev / sda1: 5 ТБ, ext4, один
    диск
  • Целевой том: / dev / mapper / archive-lvarchive: raid6 (mdadm) том 18 ТБ с разделом lvm
    и ext4

Необходимо переместить около 15 миллионов файлов, и некоторые из них могут быть дубликатами (я не хочу перезаписывать дубликаты).

Используемая команда (из исходного каталога) была:

ls -U |xargs -i -t mv -n {} /mnt/archive/targetDir/{}

Это продолжалось в течение нескольких дней, как и ожидалось, но я получаю ошибку все чаще и чаще. Когда он запустился, целевой диск был заполнен примерно на 70%, а сейчас - около 90%. Раньше было около 1/200 ходов, из-за которых возникали бы ошибки и ошибки, сейчас - около 1/5. Ни один из файлов не превышает 100 МБ, большинство - около 100 КБ.

Некоторая информация:

$ df -h
Filesystem                     Size  Used Avail Use% Mounted on
/dev/sdb3                      155G  5.5G  142G   4% /
none                           4.0K     0  4.0K   0% /sys/fs/cgroup
udev                           3.9G  4.0K  3.9G   1% /dev
tmpfs                          797M  2.9M  794M   1% /run
none                           5.0M  4.0K  5.0M   1% /run/lock
none                           3.9G     0  3.9G   0% /run/shm
none                           100M     0  100M   0% /run/user
/dev/sdb1                       19G   78M   18G   1% /boot
/dev/mapper/archive-lvarchive   18T   15T  1.8T  90% /mnt/archive
/dev/sda1                      4.6T  1.1T  3.3T  25% /mnt/tmp

$ df -i
Filesystem                       Inodes    IUsed     IFree IUse% Mounted on
/dev/sdb3                      10297344   222248  10075096    3% /
none                            1019711        4   1019707    1% /sys/fs/cgroup
udev                            1016768      500   1016268    1% /dev
tmpfs                           1019711     1022   1018689    1% /run
none                            1019711        5   1019706    1% /run/lock
none                            1019711        1   1019710    1% /run/shm
none                            1019711        2   1019709    1% /run/user
/dev/sdb1                       4940000      582   4939418    1% /boot
/dev/mapper/archive-lvarchive 289966080 44899541 245066539   16% /mnt/archive
/dev/sda1                     152621056  5391544 147229512    4% /mnt/tmp

Вот мой вывод:

mv -n 747265521.pdf /mnt/archive/targetDir/747265521.pdf 
mv -n 61078318.pdf /mnt/archive/targetDir/61078318.pdf 
mv -n 709099107.pdf /mnt/archive/targetDir/709099107.pdf 
mv -n 75286077.pdf /mnt/archive/targetDir/75286077.pdf 
mv: cannot create regular file ‘/mnt/archive/targetDir/75286077.pdf’: No space left on device
mv -n 796522548.pdf /mnt/archive/targetDir/796522548.pdf 
mv: cannot create regular file ‘/mnt/archive/targetDir/796522548.pdf’: No space left on device
mv -n 685163563.pdf /mnt/archive/targetDir/685163563.pdf 
mv -n 701433025.pdf /mnt/archive/targetDir/701433025.pd

Я нашел много сообщений об этой ошибке, но прогноз не подходит. Такие проблемы, как «на самом деле ваш диск заполнен» или «у вас закончились inodes» или даже «ваш / boot том заполнен». Однако, в основном, они имеют дело со сторонним программным обеспечением, вызывающим проблему из-за того, как оно обрабатывает файлы, и все они постоянны, что означает, что КАЖДЫЙ переход не выполняется.

Спасибо.

РЕДАКТИРОВАТЬ: вот образец неудачного и успешного файла:

FAILED (все еще на исходном диске)

ls -lhs 702637545.pdf
16K -rw-rw-r-- 1 myUser myUser 16K Jul 24 20:52 702637545.pdf

УСПЕШНО (На целевом объеме)

ls -lhs /mnt/archive/targetDir/704886680.pdf
104K -rw-rw-r-- 1 myUser myUser 103K Jul 25 01:22 /mnt/archive/targetDir/704886680.pdf

Кроме того, в то время как не все файлы терпят неудачу, файл, который терпит неудачу, ВСЕГДА терпит неудачу. Если я повторяю это снова и снова, это соответствует.

РЕДАКТИРОВАТЬ: некоторые дополнительные команды на запрос @mjturner

$ ls -ld /mnt/archive/targetDir
drwxrwxr-x 2 myUser myUser 1064583168 Aug 10 05:07 /mnt/archive/targetDir

$ tune2fs -l /dev/mapper/archive-lvarchive
tune2fs 1.42.10 (18-May-2014)
Filesystem volume name:   <none>
Last mounted on:          /mnt/archive
Filesystem UUID:          af7e7b38-f12a-498b-b127-0ccd29459376
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr dir_index filetype needs_recovery extent 64bit flex_bg sparse_super huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              289966080
Block count:              4639456256
Reserved block count:     231972812
Free blocks:              1274786115
Free inodes:              256343444
First block:              0
Block size:               4096
Fragment size:            4096
Group descriptor size:    64
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         2048
Inode blocks per group:   128
RAID stride:              128
RAID stripe width:        512
Flex block group size:    16
Filesystem created:       Thu Jun 25 12:05:12 2015
Last mount time:          Mon Aug  3 18:49:29 2015
Last write time:          Mon Aug  3 18:49:29 2015
Mount count:              8
Maximum mount count:      -1
Last checked:             Thu Jun 25 12:05:12 2015
Check interval:           0 (<none>)
Lifetime writes:          24 GB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:           256
Required extra isize:     28
Desired extra isize:      28
Journal inode:            8
Default directory hash:   half_md4
Directory Hash Seed:      3ea3edc4-7638-45cd-8db8-36ab3669e868
Journal backup:           inode blocks

$ tune2fs -l /dev/sda1
tune2fs 1.42.10 (18-May-2014)
Filesystem volume name:   <none>
Last mounted on:          /mnt/tmp
Filesystem UUID:          10df1bea-64fc-468e-8ea0-10f3a4cb9a79
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              152621056
Block count:              1220942336
Reserved block count:     61047116
Free blocks:              367343926
Free inodes:              135953194
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      732
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         4096
Inode blocks per group:   256
Flex block group size:    16
Filesystem created:       Thu Jul 23 13:54:13 2015
Last mount time:          Tue Aug  4 04:35:06 2015
Last write time:          Tue Aug  4 04:35:06 2015
Mount count:              3
Maximum mount count:      -1
Last checked:             Thu Jul 23 13:54:13 2015
Check interval:           0 (<none>)
Lifetime writes:          150 MB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:           256
Required extra isize:     28
Desired extra isize:      28
Journal inode:            8
Default directory hash:   half_md4
Directory Hash Seed:      a266fec5-bc86-402b-9fa0-61e2ad9b5b50
Journal backup:           inode blocks
Chris.Caldwell
источник
Копируются ли файлы в несколько каталогов, или вы пытаетесь записать 1,5 М файлы в один целевой каталог?
Снупи
не 1,5м, 15м и да, все в одном каталоге. На самом деле там уже более 40 метров, и еще около 30 миллионов.
Chris.Caldwell
о, смотрите, случайный тролль понизился снова. Я не думаю, что вы хотели бы упомянуть, ПОЧЕМУ вы понижаете?
Chris.Caldwell
1
Вероятно, отрицательное голосование было вызвано тем, что ваш вопрос лучше подходит для Unix.stackexchange или askubuntu, поскольку он не связан с программированием. Если в ваших тегах нет языка программирования, он, скорее всего, получит отрицательный голос.
технозавр
@ Крис - кажется , похож на этот вопрос на SF: serverfault.com/questions/384541/...
Snoopy

Ответы:

25

Ошибка в реализации функции ext4, dir_indexкоторую вы используете в целевой файловой системе.

Решение: воссоздать файловую систему без dir_index. Или отключите функцию с помощью tune2fs (требуется некоторая осторожность, см. Связанную ссылку Novell SuSE 10/11: отключить индексирование H-дерева в файловой системе ext3, которая, хотя и относится к ext3, может потребовать аналогичной осторожности.

(get a really good backup made of the filesystem)
(unmount the filesystem)
tune2fs -O ^dir_index /dev/foo
e2fsck -fDvy /dev/foo
(mount the filesystem)

В ext4 по умолчанию включена функция dir_index, которая довольно восприимчива к хеш-коллизиям.

......

У ext4 есть возможность хэшировать имена файлов своего содержимого. Это повышает производительность, но имеет «небольшую» проблему: ext4 не увеличивает свою хэш-таблицу, когда начинает заполняться. Вместо этого он возвращает -ENOSPC или «на устройстве не осталось места».

Стив
источник
3
о дерьмо, это звучит так же, как это, и как полная боль, чтобы исправить. Это около месяца, чтобы переписать. это можно сделать без потери содержимого? Я должен буду исследовать dir_index и т.д. больше завтра. Вау, никогда бы не подумал об этом.
Chris.Caldwell
Добавлена ​​команда tune2fs для отключения индексов, на случай если вы захотите это сделать.
Стив
6
Хорошо заметили @steve. К сожалению, отключение dir_index, вероятно, снизит производительность доступа с 70-метровыми файлами в одном каталоге
mjturner
3
Да. Мне не нужна пиковая производительность, но поиск по каждому файлу был бы ужасным. Так что теперь я смотрю на xfs или массив из 10k или около того подпапок. Подпапки - разумное решение, однако с ext4 я все еще рискую столкнуться. xfs страдает от той же проблемы? Я читал, что в нем используется дерево B +, но это не так много значит для меня, поскольку в нем никогда не бывает коллизий. Существует целый мир дезинформации, и я слышал, как он утверждает, что он значительно замедляет более миллиона файлов, и утверждает, что это не так.
Chris.Caldwell
2
Я думаю, что это отличный ответ, и я хотел бы отметить его как таковой, но я думаю, что было бы неплохо, если бы мы могли прийти к решению, а не просто к диагнозу. Кто-нибудь знает, страдает ли xfs чем-то подобным? Я читал смешанные отзывы, что он хорошо масштабируется, или не более 1 метра.
Chris.Caldwell
8

Предложения по выбору лучше, чем ext4 для хранения масс маленьких файлов:

Если вы используете файловую систему в качестве хранилища объектов, вам может потребоваться использовать файловую систему, которая специализируется на этом, возможно, в ущерб другим характеристикам. В результате быстрого поиска Google был обнаружен Ceph , который, похоже, имеет открытый исходный код и может быть смонтирован как файловая система POSIX, но также доступен с другими API. Я не знаю, стоит ли использовать на одном хосте, не используя преимущества репликации.

Еще одна система хранения объектов - OpenStack's Swift . В его проектных документах говорится, что каждый объект хранится в отдельном файле с метаданными в xattrs . Вот статья об этом. В их руководстве по развертыванию говорится, что XFS обеспечивает наилучшую производительность для хранения объектов. Таким образом, хотя рабочая нагрузка и не является лучшей в XFS, она явно превосходила конкурентов, когда RackSpace проводил испытания. Возможно, Swift предпочитает XFS, потому что XFS имеет хорошую / быструю поддержку расширенных атрибутов. Возможно, что ext3 / ext4 будет хорошо работать на отдельных дисках в качестве бэкэнда хранилища объектов, если дополнительные метаданные не понадобятся (или если они будут храниться в двоичном файле).

Swift выполняет репликацию / балансировку нагрузки за вас и предлагает вам предоставить ей файловые системы, созданные на необработанных дисках, а не RAID . Это указывает на то, что его рабочая нагрузка по существу является наихудшей для RAID5 (что имеет смысл, если мы говорим о рабочей нагрузке с записью небольших файлов. Обычно XFS не вполне упаковывает их один на один, поэтому не стоит получить записи с полной полосой, а RAID5 должен выполнить некоторые операции чтения для обновления полосы четности. В документах Swift также говорится об использовании 100 разделов на диске. Я предполагаю, что это термин Swift, и речь не идет о создании 100 различных файловых систем XFS на каждой SATA диск.

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

Если у вас уже есть программное обеспечение, созданное для использования файловой системы непосредственно в качестве хранилища объектов, вместо того, чтобы использовать что-то вроде Swift для управления репликацией / балансировкой нагрузки, тогда вы, по крайней мере, можете избежать размещения всех своих файлов в одном каталоге. (Я не видел, чтобы документы Swift говорили, как они размещают свои файлы в нескольких каталогах, но я уверен, что они делают.)

Почти с любой нормальной файловой системой это поможет использовать такую ​​структуру, как

1234/5678   # nested medium-size directories instead of
./12345678   # one giant directory

Вероятно, разумно около 10 тыс. Записей, поэтому легко распределить 4 знака имен ваших объектов и использовать их в качестве каталогов. Это не должно быть очень хорошо сбалансировано. Нечетный каталог 100 КБ, вероятно, не будет заметной проблемой, равно как и некоторые пустые каталоги.

XFS не идеален для огромных масс маленьких файлов. Он делает то, что может, но он более оптимизирован для потоковой записи больших файлов. Это в целом очень хорошо для общего использования. Он не сталкивается ENOSPCс коллизиями в своей индексации каталогов (AFAIK) и может обрабатывать один каталог с миллионами записей. (Но все же лучше использовать хотя бы одноуровневое дерево.)

Дейв Чиннер дал несколько комментариев о производительности XFS с огромным количеством выделенных inode , что привело к снижению touchпроизводительности. Поиск свободного инода для выделения начинает занимать больше процессорного времени, так как битмап свободного инода фрагментируется. Обратите внимание, что это не проблема одного большого каталога против нескольких каталогов, а скорее проблема многих используемых inode во всей файловой системе. Разделение ваших файлов на несколько каталогов помогает справиться с некоторыми проблемами, такими как та, что ext4 захлебнулась в OP, но не с проблемой всего диска, связанной с отслеживанием свободного места. В этом помогает отдельная файловая система на диске Swift по сравнению с гигантской XFS на RAID5.

Я не знаю , хорош ли btrfs в этом, но я думаю, что это может быть. Я думаю, что Facebook нанимает своего ведущего разработчика по причине. : P Некоторые тесты, которые я видел, такие как распаковка исходного кода ядра Linux, показывают, что btrfs хорошо работает.

Я знаю, что reiserfs был оптимизирован для этого случая, но он почти не поддерживается. Я действительно не могу рекомендовать идти с reiser4. Впрочем, было бы интересно поэкспериментировать. Но это, безусловно, наименее перспективный выбор. Я также видел сообщения о снижении производительности на устаревших reiserFS, и нет хорошего инструмента для дефрагментации. (Google filesystem millions of small files, и посмотрите на некоторые из существующих ответов stackexchange.)

Я, вероятно, что-то упускаю , поэтому окончательная рекомендация: спросите об этом на сервере! Если бы мне пришлось что-то выбрать прямо сейчас, я бы сказал, попробуйте BTRFS, но убедитесь, что у вас есть резервные копии. (Особенно, если вы используете встроенную многодисковую избыточность BTRFS вместо того, чтобы запускать ее поверх RAID. Преимущества производительности могут быть большими, поскольку небольшие файлы - плохие новости для RAID5, если только это не рабочая нагрузка, предназначенная в основном для чтения.)

Питер Кордес
источник
1
Спасибо. Я видел, как многие люди использовали подпапки, и на самом деле много лет назад у меня было такое решение на другой установке, но это еще один уровень, которого я надеялся избежать. Похоже, что издержки от этого будут гораздо меньше, чем поиск ФС, который просто работает для этой цели. RE: XFS, это удивительно, что это так плохо при большом количестве файлов, так как часто дается ответ коленного рефлекса. BTRFS, вики: «записи каталога отображаются в виде элементов каталога, значения правых ключей которых являются хешем CRC32C их имени файла». разве не та же проблема у нас?
Chris.Caldwell
@ Chris.Caldwell: Вам нужно проверить, но я предполагаю, что BTRFS обрабатывает коллизии хеша, поддерживая несколько записей в одном хэш-контейнере, а не ENOSPC. Задумывались ли вы о том, чтобы просто хранить свои вещи в базе данных, а не в отдельных файлах в файловой системе? Мне никогда не приходилось создавать систему для обработки таких данных. Я использую XFS, которая отлично подходит для того, для чего я ее использую (для хранения видео, а также исходного кода и прочего Unix общего назначения.)
Питер Кордес
1
При проектировании файловых систем уровень каталогов меньше. Два быстрых поиска в небольших таблицах будут быстрее, чем один медленный поиск в переполняющейся таблице, в которой хранится больше данных, чем было оптимизировано. Как я уже сказал, вам не нужно идеально распределять свои файлы по каталогам, поэтому вы можете просто взять первые 4 символа ваших имен файлов и вставить a /. Надеюсь, это не повлияет на слишком много мест в вашем коде. (Вы должны убедиться, что каталоги созданы, если создание нового файла не удается с помощью ENOENT). Спросите на serverfault, есть ли другие файловые системы.
Питер Кордес
@ Chris.Caldwell: я действительно должен скопировать этот ответ на вопрос, где это актуально. Есть несколько существующих. Мне было любопытно, что «предполагается» использовать для хранения объектов, и я нашел несколько документов о Swift. По-видимому, он хранит объекты в виде отдельных файлов в XFS (но с отдельной XFS для каждого диска, а не RAID. Он сам выполняет избыточность).
Питер Кордес
1

Для решения этой проблемы ниже, что я сделал, чтобы исправить (вам может потребоваться доступ sudo для следующих шагов):

  1. Используемое пространство Inodes было 100%, которое можно получить с помощью команды ниже

    df -i /

Используемые inode файловой системы, если% IUse% установлен на

/dev/xvda1            524288   524288  o     100% /
  1. Необходимо освободить iNoted, следовательно, нужно найти файлы с числом узлов i, используя следующую команду:

Попробуйте найти, если это проблема inode с:

df -ih

Попробуйте найти корневые папки с большим количеством инодов:

for i in /*; do echo $i; find $i |wc -l; done

Попробуйте найти конкретные папки:

for i in /src/*; do echo $i; find $i |wc -l; done
  1. теперь мы обнулили папку с большим количеством файлов в ней. Выполните приведенные ниже команды одну за другой, чтобы избежать ошибок (в моем случае действительной папкой была / var / spool / clientmqueue):
find /var/spool/clientmqueue/ -type f -mtime +1050 -exec rm -f {} +

find /var/spool/clientmqueue/ -type f -mtime +350 -exec rm -f {} +

find /var/spool/clientmqueue/ -type f -mtime +150 -exec rm -f {} +

find /var/spool/clientmqueue/ -type f -mtime +50 -exec rm -f {} +
Барани р
источник