Назад | Перейти на главную страницу

Ошибка «На устройстве не осталось места», несмотря на то, что на btrfs достаточно места

Почти везде получаются сбои в логах с жалобами на No space left on device

Журналы Gitlab:

==> /var/log/gitlab/nginx/current <==
2016-11-29_20:26:51.61394 2016/11/29 20:26:51 [emerg] 4871#0: open() "/var/opt/gitlab/nginx/nginx.pid" failed (28: No space left on device)

Журналы электронной почты Dovecot:

Nov 29 20:28:32 aws-management dovecot: imap(email@www.sitename.com): Error: open(/home/vmail/emailuser/Maildir/dovecot-uidlist.lock) failed: No space left on device

Выход df -Th

Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/xvda1     ext4      7.8G  3.9G  3.8G  51% /
devtmpfs       devtmpfs  1.9G   28K  1.9G   1% /dev
tmpfs          tmpfs     1.9G   12K  1.9G   1% /dev/shm
/dev/xvdh      btrfs      20G   13G  7.9G  61% /mnt/durable
/dev/xvdh      btrfs      20G   13G  7.9G  61% /home
/dev/xvdh      btrfs      20G   13G  7.9G  61% /opt/gitlab
/dev/xvdh      btrfs      20G   13G  7.9G  61% /var/opt/gitlab
/dev/xvdh      btrfs      20G   13G  7.9G  61% /var/cache/salt

Похоже, что места для inode достаточно. Выход df -i

Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/xvda1     524288 105031 419257   21% /
devtmpfs       475308    439 474869    1% /dev
tmpfs          480258      4 480254    1% /dev/shm
/dev/xvdh           0      0      0     - /mnt/durable
/dev/xvdh           0      0      0     - /home
/dev/xvdh           0      0      0     - /opt/gitlab
/dev/xvdh           0      0      0     - /var/opt/gitlab
/dev/xvdh           0      0      0     - /var/cache/salt

Выход btrfs fi show

Label: none  uuid: 6546c241-e57e-4a3f-bf43-fa933a3b29f9
        Total devices 4 FS bytes used 11.86GiB
        devid    1 size 10.00GiB used 10.00GiB path /dev/xvdh
        devid    2 size 10.00GiB used 9.98GiB path /dev/xvdi
        devid    3 size 10.00GiB used 9.98GiB path /dev/xvdj
        devid    4 size 10.00GiB used 9.98GiB path /dev/xvdk

Выход btrfs fi df /mnt/durable

Data, RAID10: total=17.95GiB, used=10.12GiB
Data, single: total=8.00MiB, used=0.00
System, RAID10: total=16.00MiB, used=16.00KiB
System, single: total=4.00MiB, used=0.00
Metadata, RAID10: total=2.00GiB, used=1.74GiB
Metadata, single: total=8.00MiB, used=0.00
unknown, single: total=272.00MiB, used=8.39MiB

Что могло быть причиной этого? Я использую базовую версию ядра linux AMI ec2 4.4.5-15.26.amzn1.x86_64

Обновить

Выполнение команды, предложенной ниже btrfs fi balance start -dusage=5 /mnt/durable вернул мне ошибку следующего:

ERROR: error during balancing '/mnt/durable' - No space left on device There may be more info in syslog - try dmesg | tail

После ручного удаления кучи больших файлов общим размером ~ 1 ГБ я перезагрузил компьютер и попытался снова, убедившись, что использую sudo, и команда была выполнена. Затем я снова перезагрузил свою машину, и, похоже, проблема решена.

Добро пожаловать в мир BTRFS. У него есть некоторые заманчивые особенности, но есть и некоторые раздражающие проблемы.

Во-первых, некоторая информация о вашей настройке, похоже, у вас есть четыре диска в томе «raid 10» BTRFS (поэтому все данные хранятся дважды на разных дисках). Этот том BTRFS затем разделяется на подобтомы в разных точках монтирования. Подтомы имеют общий пул дискового пространства, но имеют отдельные номера inode и могут быть смонтированы в разных местах.

BTRFS выделяет пространство «фрагментами», фрагмент выделяется определенному классу данных или метаданных. Что может случиться (и похоже, что произошло в вашем случае), так это то, что все свободное пространство распределяется по блокам данных, не оставляя места для метаданных.

Также кажется, что (по причинам, которые я не полностью понимаю), что BTRF «исчерпывает» пространство метаданных до того, как показатель доли используемого пространства метаданных достигает 100%.

Похоже, именно это и произошло в вашем случае: имеется много свободного места для данных, но нет свободного места, которое не было выделено для фрагментов, и недостаточно свободного места в существующих фрагментах метаданных.

Исправление - запустить «ребалансировку». Это переместит данные, так что некоторые фрагменты можно будет вернуть в «глобальный» пул свободных мест, где они могут быть перераспределены как фрагменты метаданных.

btrfs fi balance start -dusage=5 /mnt/durable

Число после -dusage устанавливает, насколько агрессивна перебалансировка, то есть насколько близко должны быть пустые блоки, чтобы их можно было перезаписать. Если баланс говорит, что было переписано 0 блоков, попробуйте еще раз с более высоким значением -dusage.

Если баланс не работает, я бы попробовал перезагрузить и / или освободить место, удалив файлы.

Поскольку вы используете btrfs с настройкой RAID, попробуйте выполнить операцию балансировки.

btrfs balance start /var/opt/gitlab

Если это дает ошибку о нехватке места, попробуйте еще раз, используя этот синтаксис:

btrfs balance start -musage=0 -dusage=0 -susage=0 /var/opt/gitlab 

Повторите эту операцию для каждой файловой системы btrfs, где вы видите ошибки, связанные с пространством. Если проблема с пространством связана с тем, что метаданные не распределяются по зеркальным дискам, это может освободить для вас место.

В моей системе я добавил следующее задание в cron.monthly.

В clear_cache remount возникает из-за некоторых проблем с коррупцией, которые были у btrfs с бесплатными картами. (Думаю, они наконец нашли проблему, но проблема настолько меня раздражает, что я готов платить за восстановление карт один раз в месяц.)

Я наращиваю usage варианты постепенного освобождения места для больших и больших балансов.

#!/bin/sh

for mountpoint in `mount -t btrfs | awk '{print $3}' | sort -u`
do
    echo --------------------------
    echo Balancing $mountpoint :
    echo --------------------------
    echo remount with clear_cache...
    mount -oremount,clear_cache $mountpoint
    echo Before:
    /usr/sbin/btrfs fi show $mountpoint
    /usr/sbin/btrfs fi df $mountpoint
    for size in 0 1 5 10 20 30 40 50 60 70 80 90
    do
        time /usr/sbin/btrfs balance start -v -musage=$size $mountpoint 2>&1
        time /usr/sbin/btrfs balance start -v -dusage=$size $mountpoint 2>&1
    done
    echo After:
    /usr/sbin/btrfs fi show $mountpoint
    /usr/sbin/btrfs fi df $mountpoint
done

Если вы дошли до точки, когда вы не можете выполнить ребалансировку из-за недостатка места, рекомендуется временно добавить другое блочное устройство (или устройство обратной связи на другом диске) какого-либо типа на ваш том на время перебалансировки, а затем убери это.

Это не столько проблема с btrfs, сколько то, что было сделано с этой системой. Это похоже на результат неполной перебалансировки с «единственной» политики выделения на политику выделения «рейд 10», о чем свидетельствует большое количество отдельных выделенных блоков. Вероятно, он начинался как одиночный, а затем преобразование было прервано. Пул с таким непоследовательным распределением обязательно будет иметь ... ну, проблемы с распределением.

Учтите, что у вас израсходован 61% пула. Ваша политика распределения - RAID10, так что это должно привести к максимальному потреблению пула 50% перед достижением полного, поскольку все реплицируется 2. Вот почему ваше преобразование с одиночного на RAID 10 не удалось (и продолжает). Я могу только догадываться, но, вероятно, он был выделен в середине ребалансировки. На вашем устройстве не осталось места для перебалансировки в RAID 10 с имеющимися дисками. Единственная причина, по которой вы достигли 61%, заключается в том, что ваши диски распределены несогласованно, некоторые - линейно с одним распределением, а большинство - в RAID 10.

Вы можете перебалансировать к единой политике распределения, если хотите освободить место, ничего не меняя. Вы также можете добавить больше дисков или увеличить размер дисков. ИЛИ вы можете, как вы это сделали в этом случае, просто удалить кучу файлов, чтобы ваш пул мог фактически сбалансироваться с RAID 10 (так как он будет потреблять менее 50% в целом). Убедитесь, что вы перебалансировали после удаления файлов, иначе у вас все еще будет эта дрянная политика распределения.

В частности, принудительно применяйте RAID 10 при перебалансировке после удаления этих файлов, чтобы убедиться, что вы избавились от этих отдельных выделенных блоков, например:

btrfs fi balance start -dconvert=raid10 -mconvert=raid10 /home