btrfs «уронил» сервер

Заметки по вчерашнему падению сервера.

Во время тренировки начал периодически получать сообщения на почту. Оказалось, проблема с запуском контейнера cron-апдейтера у Nextcloud — не может достучаться до базы. При этом все остальное работало. Подключаюсь mysql-клиентом с хоста — подключается. Но. При выходе получаю

MariaDB [(none)]> ^Dmysql: Error on rename of '/root/.mysql_history.TMP' to '/root/.mysql_history' (Errcode: 28 "No space left on device")

Места — полно. На днях как раз устроил чистку, добавил пачку скриптов по оптимизации БД — в общем, добавилось почти 10 ГБ свободного места. Лимита инод у btrfs нет. Вручную создать файл в /root могу. Откуда проблема — непонятно. Между делом грохнул старые логи у journald и логи репликации у mysql, чтобы освободить еще больше места.

Обрисовал проблему гуглоИИ, в итоге по подсказкам сначала уронил сервер целиком (вероятно, тут и мой косяк), потом получилось все исправить.

Смотрим:

btrfs filesystem usage /

В моем случае выглядело так:

Device size: 48.00GiB
Device allocated: 48.00GiB
Device unallocated: 2.00MiB

Я не особо обратил внимание — думал, что-то в стиле LVM’а, когда блоки могут быть привязаны к какой-то ФС, а могут быть не привязаны, но проблемы полное использование блоков обычно не составляет. Тут все в рамках одной ФС, поэтому проблема была не особо очевидна. ГуглоИИ сразу сказал, что тут проблема и надо делать

btrfs balance start -dusage=80 /

За цифру (и -dusage, а не -musage) не ручаюсь, диалог не сохранился, но что-то в этом роде. Так или иначе, была ругань на нехватку места, советы про уменьшение значения параметра, но даже с -dusage=1 ничего не получалось. Из советов дальше — создать пустой файл, подключить его как loop-устройство, расширить корень, а дальше пробовать делать баланс, постепенно повышая параметр. Видя то, что файлы на разделе я могу создать — гигабайтный файлик я создал в корневом разделе, исходя из того, что в оперативке (в tmpfs) делать такое тесновато. Успешно подключил как loop, а вот на btrfs device add /dev/loop0 / все и повисло: получил сообщение про то, что делается TRIM, дальше была очень долгая отправка сообщений в чат и тому подобное. Отменить команду — нельзя, выполнить другую субкоманду — тоже нельзя.

Пришлось отправить сервер в ребут. Часть сервисов завершилась, часть systemd обещал погасить только через 10 минут. Пришлось перезагружать через панель хостера. Сервер, к счастью, поднялся. Повторил процедуру, но в этот раз сделал 300 МБ файл в tmpfs. Все прошло успешно, файл подключился, смог запустить балансировку в несколько проходов. Итог — почти 7 ГБ свободных блоков:

    Device size:                  48.00GiB
    Device allocated:             40.94GiB
    Device unallocated:            7.06GiB

После чего смог отключить loop-устройство и удалить файл из tmpfs.

По итогу… Добавил в cron кроме давно уже висящей там дефрагментации еще и балансировку в несколько этапов:

22 5 */3 * * /usr/bin/btrfs filesystem defrag -r -f /
0 3 * * * /usr/bin/btrfs balance start -dusage=0 -musage=0 / > /dev/null 2>&1
0 4 * * 0 /usr/bin/btrfs balance start -dusage=5 -musage=5 / > /dev/null 2>&1
0 4 * * 1 /usr/bin/btrfs balance start -dusage=15 -musage=15 / > /dev/null 2>&1
0 4 * * 2 /usr/bin/btrfs balance start -dusage=35 -musage=35 / > /dev/null 2>&1

Вот, кстати, да, «0» в параметрах в процессе экспериментов я, кажется, не пробовал.

Позже уже нашел тред на ЛОРе с подобным рецептом — ну и в целом обсуждение по теме.

Оттуда же узнал про пакет btrfsmaintenance, присутствующий и в Debian. У себя пока решил не ставить, так как более гибко решаю основные задачи по обслуживанию через cron. Но в целом — стоит держать в памяти.

Update 2026-08-25: а не хватило такого блока в cron’e, снова была нехватка места. В итоге добавил на каждый день 55/55.

Полный список команд для истории и быстрой копипасты

dd if=/dev/zero of=/tmp/btrfs_warp.img bs=1M count=300
losetup -f --show /tmp/btrfs_warp.img
btrfs device add /dev/loop0 /
/usr/bin/btrfs balance start -dusage=55 -musage=55 /
btrfs device remove /dev/loop0 /
losetup -d /dev/loop0
rm /tmp/btrfs_warp.img

[свернуть]

Добавить комментарий