Btrfs – отсутствует пространство – 40% разница между du и df

Вопрос или проблема

У меня есть диск btrfs (без рейда), который показывает очень большую разницу между du и df:

$ df -h /pgdata
Filesystem                     Size  Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-pgdata   85G   77G  7.1G  92% /pgdata

$ du -sh /pgdata
56G     /pgdata

И команды btrfs дают мне тот же результат:

$ btrfs fi df -h /pgdata/
Data, single: total=82.94GiB, used=75.63GiB
System, DUP: total=32.00MiB, used=16.00KiB
Metadata, DUP: total=1.00GiB, used=365.73MiB
GlobalReserve, single: total=228.33MiB, used=0.00B

$ btrfs fi du -s /pgdata/
     Total   Exclusive  Set shared  Filename
  55.84GiB    55.36GiB   491.34MiB  /pgdata/

Нет подтомов (как я думаю), btrfs subvolume list /pgdata пуст.
Я запустил btrfs balance start /pgdata/ -dusage=66, но это особо не изменило ситуацию.

$ btrfs fi usage /pgdata/
Overall:
    Device size:                  85.00GiB
    Device allocated:             85.00GiB
    Device unallocated:            1.00MiB
    Device missing:                  0.00B
    Used:                         76.50GiB
    Free (estimated):              7.15GiB      (min: 7.15GiB)
    Data ratio:                       1.00
    Metadata ratio:                   2.00
    Global reserve:              228.52MiB      (used: 0.00B)

Data,single: Size:82.94GiB, Used:75.79GiB (91.38%)
   /dev/mapper/ubuntu--vg-pgdata          82.94GiB

Metadata,DUP: Size:1.00GiB, Used:365.78MiB (35.72%)
   /dev/mapper/ubuntu--vg-pgdata           2.00GiB

System,DUP: Size:32.00MiB, Used:16.00KiB (0.05%)
   /dev/mapper/ubuntu--vg-pgdata          64.00MiB

Unallocated:
   /dev/mapper/ubuntu--vg-pgdata           1.00MiB

Это не удалённые иноды являются проблемой (машина была перезагружена 3 часа назад) и:

$ lsof /pgdata |grep deleted
postgres  4107 postgres    4u   REG   0,58   16777216 238658 /pgdata/postgresql/13/main/pg_wal/00000001000001E40000008A (deleted)
postgres  5589 postgres   45u   REG   0,58   16777216 238753 /pgdata/postgresql/13/main/pg_wal/00000001000001E50000000E (deleted)
postgres  5590 postgres   45u   REG   0,58   16777216 222523 /pgdata/postgresql/13/main/pg_wal/00000001000001E40000006A (deleted)
postgres  5591 postgres   26u   REG   0,58   16777216 238992 /pgdata/postgresql/13/main/pg_wal/00000001000001E4000000F3 (deleted)
postgres  5592 postgres   52u   REG   0,58   16777216 238986 /pgdata/postgresql/13/main/pg_wal/00000001000001E4000000ED (deleted)
postgres  5595 postgres   28u   REG   0,58   16777216 238995 /pgdata/postgresql/13/main/pg_wal/00000001000001E4000000F6 (deleted)
postgres  5596 postgres   19u   REG   0,58   16777216 222523 /pgdata/postgresql/13/main/pg_wal/00000001000001E40000006A (deleted)
postgres  5597 postgres   44u   REG   0,58   16777216 222523 /pgdata/postgresql/13/main/pg_wal/00000001000001E40000006A (deleted)
postgres  5598 postgres   12u   REG   0,58   16777216 238986 /pgdata/postgresql/13/main/pg_wal/00000001000001E4000000ED (deleted)
postgres  5604 postgres   85u   REG   0,58   16777216 238988 /pgdata/postgresql/13/main/pg_wal/00000001000001E4000000EF (deleted)
postgres  5605 postgres   61u   REG   0,58   16777216 238986 /pgdata/postgresql/13/main/pg_wal/00000001000001E4000000ED (deleted)
postgres 12936 postgres   58u   REG   0,58   16777216 238995 /pgdata/postgresql/13/main/pg_wal/00000001000001E4000000F6 (deleted)

Я нашёл другие сообщения об этой проблеме, но ни в одном не было такой большой разницы (примерно на 40% больше, чем должно быть) и это всегда были метаданные или снимок. Здесь, похоже, это не так.

У кого-нибудь есть идея, почему не хватает 20GiB свободного места?

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

Чтобы анализировать такие проблемы, я создал btdu, профилировщик использования диска для btrfs:

https://github.com/CyberShadow/btdu

Инструмент определит истинную причину расхождения.

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

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

Я заметил ту же “проблему” (потеря более 28% на терабайтной файловой системе BTRFS) в настройке, где у меня есть виртуальные машины, хранящиеся на большой файловой системе BTRFS, и каждая VM использует COW VMDK файлы в качестве дисков, а некоторые VM работают с базами данных (особенно MariaDB / postgreSQL)

Способ вернуть большую часть этого пространства был следующим:

$ sudo btrfs balance start -musage=100 -dusage=100 /mnt/vm
$ sudo btrfs filesystem defrag -r -f -v /mnt/vm

и снова выполнить балансировку:

$ sudo btrfs balance start -musage=100 -dusage=100 /mnt/vm

Таким образом мне удалось вернуть большую часть “потерянного” пространства

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

btrfs filesystem

Вот результаты в моём случае:

Реальные данные (оригинальное и последнее состояние):

$ sudo btrfs fi du -s /mnt/vm
     Total   Exclusive  Set shared  Filename
 669.62GiB   669.22GiB   401.46MiB  /mnt/vm

Использование файловой системы BTRFS (оригинальное состояние)

$ sudo btrfs fi usage /mnt/vm
Overall:
    Device size:        1000.00GiB
    Device allocated:        955.07GiB
    Device unallocated:       44.93GiB
    Device missing:          0.00B
    Device slack:            0.00B
    Used:            950.71GiB
    Free (estimated):         46.74GiB  (min: 24.28GiB)
    Free (statfs, df):        46.74GiB
    Data ratio:               1.00
    Metadata ratio:           2.00
    Global reserve:      512.00MiB  (used: 0.00B)
    Multiple profiles:              no

Data,single: Size:949.01GiB, Used:947.19GiB (99.81%)
   /dev/mapper/vgu2nvme-lvvm     949.01GiB

Metadata,DUP: Size:3.00GiB, Used:1.76GiB (58.56%)
   /dev/mapper/vgu2nvme-lvvm       6.00GiB

System,DUP: Size:32.00MiB, Used:144.00KiB (0.44%)
   /dev/mapper/vgu2nvme-lvvm      64.00MiB

Unallocated:
   /dev/mapper/vgu2nvme-lvvm      44.93GiB

Последнее состояние после всех операций (первая балансировка восстановила только 10 GiB):

$ sudo btrfs fi usage /mnt/vm
Overall:
    Device size:        1000.00GiB
    Device allocated:        711.07GiB
    Device unallocated:      288.93GiB
    Device missing:          0.00B
    Device slack:            0.00B
    Used:            708.02GiB
    Free (estimated):        291.72GiB  (min: 147.26GiB)
    Free (statfs, df):       291.72GiB
    Data ratio:               1.00
    Metadata ratio:           2.00
    Global reserve:      512.00MiB  (used: 0.00B)
    Multiple profiles:              no

Data,single: Size:709.01GiB, Used:706.21GiB (99.61%)
   /dev/mapper/vgu2nvme-lvvm     709.01GiB

Metadata,DUP: Size:1.00GiB, Used:926.33MiB (90.46%)
   /dev/mapper/vgu2nvme-lvvm       2.00GiB

System,DUP: Size:32.00MiB, Used:144.00KiB (0.44%)
   /dev/mapper/vgu2nvme-lvvm      64.00MiB

Unallocated:
   /dev/mapper/vgu2nvme-lvvm     288.93GiB

Итак, не идеально (примерно 4% потерянного пространства не удалось восстановить), но это лучший результат, который я смог достичь!

Примечание: все эти операции были выполнены онлайн с файловой системой, смонтированной и с запущенными около ~ 20 VM на ней.
Возможно, единственный способ восстановить последние 4% будет в холодной копии данных на другую недавно отформатированную файловую систему BTRFS (= остановка ~20 рабочих VM и выполнение cp -a )…

Так что если кто-то знает, как восстановить последние 4% потерянного пространства без копирования данных на другую файловую систему, это было бы очень полезно.

Ответ или решение

На Btrfs-файловой системе часто наблюдаются несовпадения между командами du и df. В данном случае описывается ситуация, когда команда df показывает, что почти 77GB из 85GB заняты, в то время как du отображает лишь 56GB. Эта значительная разница может быть вызвана несколькими факторами, которые мы рассмотрим подробнее.

Возможные причины расхождения между du и df

  1. Удаленные, но еще открытые файлы: Это наиболее распространенная причина рассогласования. В вашем случае несколько файлов PostgreSQL указаны как удаленные, но продолжают оставаться в памяти, пока процесс не завершится или система не будет перезагружена.

  2. Фрагментация: Сильно фрагментированные файлы, особенно при интенсивных операциях записи, могут занимать больше места на диске, чем отображается в du. Это часто бывает с базами данных, подобными PostgreSQL.

  3. Резервное пространство Btrfs: Btrfs резервирует пространство для метаданных, глобальных резервов и других системных данных, что может не быть видимым в du.

  4. Дупликация данных: Например, использование CoW (Copy-on-Write) может привести к тому, что Btrfs фактически выделяет больше места для данных, чем кажется необходимо.

Рекомендации по решению проблемы

Оптимизация с помощью балансировки: Проведение операций балансировки с использованием параметров -musage=100 -dusage=100 может помочь перераспределить данные более эффективно, уменьшая фрагментацию и освобождая некоторое пространство. Тем не менее, вы уже попробовали btrfs balance, и возможно, его недостаточно.

Дефрагментация файловой системы: Запуск команды btrfs filesystem defrag может значительно снизить уровень фрагментации, особенно для файлов баз данных, которые часто записываются на диск небольшими блоками.

Инструменты для анализа Btrfs: Использование специализированных инструментов, таких как btdu, может дать более детальное представление о распределении пространства в Btrfs, позволяя выявить истинные причины расхождения.

Заключение

В случае Btrfs, особенно при работе с интенсивными базами данных, распределение дискового пространства может быть довольно сложным. Явное расхождение между командами du и df в вашем случае может быть связано с множеством факторов, включая фрагментацию, удаленные файлы и системные резервы. Использование балансировки и дефрагментации, а также специализированных инструментов для анализа Btrfs, сможет помочь вам оптимизировать использование пространства на файлосистеме.

Если у вас остались дополнительные вопросы или возникли трудности при выполнении рекомендованных действий, пожалуйста, не стесняйтесь обращаться за дополнительной консультацией.

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

Капча загружается...