Перейти к содержанию

Файловые системы Linux


ext4

Дефолт большинства дистрибутивов (проверенная временем) + Журналируемая

  • Стабильность, отличная поддержка инструментов (e2fsck, tune2fs, resize2fs), быстрый fsck, журнал, extents, delayed allocation.
  • Нет CoW, нет нативных снапшотов, нет компрессии, нет встроенной защиты от bitrot: checksums только для метаданных (metadata_csum), данные ext4 не проверяет.
  • Фишки: до 1 EiB, до 16 TiB на файл, tune2fs -O fast_commit ускоряет fsync, chattr +j включает журналирование данных для отдельного файла.

Note

В исходной версии: «checksums для данных - с ядра 5.4 через data_checksum» и «chattr +C для отключения журналирования на горячих файлах». Checksums данных в ext4 нет. chattr +C - флаг No_COW для Btrfs, на ext4 он не действует. Отключить журнал для одного файла ext4 не умеет, а включить журналирование его данных - chattr +j.

Архитектура: block groups + журнал

ext4 - прямая эволюция ext3/ext2. Диск нарезан на block groups фиксированного размера (обычно 128 MiB), каждая содержит свой кусок bitmap свободных блоков, таблицу inode и данные. Это даёт локальность: файл и его метаданные стараются жить в одной группе - короткий seek на HDD.

Поверх - журнал (JBD2). По умолчанию режим data=ordered: в журнал пишутся только метаданные, но данные принудительно сбрасываются на диск ДО коммита метаданных. Это компромисс между скоростью (data=writeback) и надёжностью (data=journal, где журналятся и данные тоже - медленно, зато выживает любой crash).

Extents (с ext4) вместо block maps ext3: один extent описывает непрерывный диапазон блоков одной записью. Большие файлы хранятся компактно в дереве extent'ов, поиск блока - O(log n).

Delayed allocation: ext4 не выбирает физические блоки сразу при write(), а копит изменения в памяти и аллоцирует пачкой при fsync/flush. Меньше фрагментации, лучше throughput. Обратная сторона - при питании-в-розетку терялись свежие файлы (знаменитый bug 2009 года в Ubuntu). Закрыто через auto_da_alloc, но осадочек остался.

Следствия

  • Журнал - это не CoW. Запись блока перезаписывает его на месте. В случае crash журнал даёт «откат к консистентному состоянию», а не «атомарную транзакцию для пользователя».
  • Никаких снапшотов: нет дерева версий, есть один актуальный набор inode.
  • fsck быстрый и предсказуемый - чинит конкретные структуры (bitmap, inode-таблицы, журнал), а не «перестраивает всё из CoW-дерева».

Хорошо

  • Зрелость. ext4 в проде с 2008, ext3 - с 2001. Самая обкатанная ФС в Linux. Поведение под любой нагрузкой задокументировано, у любого админа есть мускульная память на e2fsck/tune2fs/dumpe2fs.
  • Предсказуемая производительность. Нет CoW-фрагментации, нет «внезапного balance», нет sudden ENOSPC. На HDD + БД с random write ext4 часто обгоняет Btrfs/ZFS без тюнинга.
  • Лучший fsck в мире. e2fsck чинит почти всё, что не уничтожено физически: повреждённый суперблок (есть backup superblocks: mke2fs -n покажет offsets), сломанные inode, поломанные директории. Время fsck растёт с числом inode, но в разы быстрее xfs_repair.
  • Resize в обе стороны. resize2fs умеет и расширить (online), и сжать (offline, после umount). Редкая фича - XFS не умеет shrink, ZFS тоже.
  • Шифрование на уровне ФС. fscrypt - per-directory encryption (как в Android/ChromeOS). Не требует LUKS, можно шифровать только /home или конкретные подпапки.
  • Прогноз: будет работать всегда. ext4 не зависит от модной фичи года или конфликта мейнтейнеров. bcachefs из ядра уже выпилили, а ext4 останется.

Плохо

  • Нет CoW - нет снапшотов, нет атомарных переключений версий конфига/контейнера. Хочешь снапшот
  • лезь в LVM thin снизу.
  • Нет checksums данных. Если диск молча испортит блок (bitrot), ext4 этого не заметит - отдаст битый блок приложению. На enterprise SSD/HDD с end-to-end protection это менее остро, на consumer-железе с большими объёмами - реальный риск.
  • Нет компрессии. Логи, дампы, текстовые данные занимают полный размер. Лечится только на уровне приложения (gzip/zstd на pipeline'е).
  • Нет нативного multi-device. ext4 живёт на одном блочном устройстве. Нужен RAID - mdraid снизу, нужен пул дисков - LVM. Стек получается многоэтажный.
  • Фрагментация на долгоживущих директориях с миллионами мелких файлов. Не катастрофа, но e4defrag существует не просто так.
  • Inode-таблица фиксирована при mkfs. mkfs.ext4 -N или -i задают число inode. Если упёрся - единственный путь mkfs заново. На FS с миллионами мелких файлов (mail spool) это реальная проблема. XFS и Btrfs аллоцируют inode динамически.

Грабли

  1. Inode exhaustion при свободном месте. df -i показывает 100% used, df - 30%. Лечения «на лету» нет, только mkfs.
  2. data=writeback теряет данные при crash, но включают «для скорости» - потом удивляются.
  3. fsck требует umount: для корня - single-user или fsck.mode=force через initramfs.
  4. resize2fs shrink требует e2fsck сначала, сжимать можно только до объёма используемых данных.
  5. Discard/TRIM: монтировать с discard замедляет delete на SSD, правильнее fstrim по cron/таймеру systemd.

XFS

Дефолт в RHEL/Rocky/Alma. Заточена под крупные файлы и параллелизм.

  • Отличный throughput на больших файлах и многопоточной нагрузке (allocation groups), online defrag (xfs_fsr), reflinks (CoW-копии файлов), DAX, real-time subvolume.
  • Уменьшать (shrink) нельзя. С ядра 5.12 есть экспериментальное уменьшение только в пределах свободного места последней AG, на практике его не используют. Тяжелее ext4 на мелких файлах. fsck требует много памяти.
  • Фишки: xfs_io -c "reflink" - мгновенные CoW-копии, идеально для контейнерных образов и снапшотов БД.

Архитектура: allocation groups + B+ деревья + журнал

XFS родилась в Silicon Graphics (IRIX, 1993) для видеомонтажа и научных вычислений - то есть для очень больших файлов и многотерабайтных томов на multi-CPU машинах. Это вся ДНК ФС.

Диск делится на Allocation Groups (AG) - обычно 4 и более, каждая со своими структурами учёта (free space btree по offset и по size, inode btree, reverse-mapping btree с v5). AG - это не block group ext4: каждая AG работает почти независимо, со своим локом, поэтому параллельные write'ы в разные файлы идут параллельно в разные AG без contention. Отсюда легендарный scalability на NUMA-машинах.

Inode аллоцируются динамически - нет глобальной таблицы как в ext4. Сколько надо мелких файлов - столько inode. Лимит - свободное место.

Всё внутри - B+ деревья. Свободные блоки, экстенты файлов, inode, директории, ACL, reverse-map. Поэтому XFS отлично масштабируется на 100M+ файлов в директории, на терабайтные файлы, на тысячи параллельных потоков. ext4 на таком захлёбывается.

Журнал - metadata-only (как ext4 data=ordered, своего data=journal-режима нет). По умолчанию internal (на том же AG-0), можно вынести на отдельное устройство (-l logdev=) - пишут на NVRAM или быстрый SSD в HPC-конфигурациях.

Delayed allocation, speculative preallocation (XFS заранее резервирует чуть больше места при росте файла, чтобы избежать фрагментации), extent hint'ы.

Версия v5 on-disk format (с 2014, дефолт с RHEL 7.3): CRC32 на ВСЕ метаданные, reverse-mapping (rmapbt) для self-healing, reflinks. Старые v4 в RHEL 9 deprecated.

Следствия

  • На больших файлах и параллельной нагрузке (БД, Kafka, MinIO, видеостриминг, HPC) XFS почти всегда быстрее ext4 и предсказуемее Btrfs.
  • На массе мелких файлов (mail, мелкие конфиги, исходники) ext4 чуть шустрее из-за более компактных директорий и меньшего overhead AG.
  • Журнал не защищает данные, только метаданные. После crash файл может быть «частично записан» с дырой нулей. fsync делает то, что должен, mount option sync - для параноиков.
  • Shrink невозможен в принципе. AG-структуры аллоцированы по всему тому, переехать не могут. Это by design, не «не успели реализовать».

Хорошо

  • Производительность на больших и параллельных нагрузках. Confluent рекомендует XFS для Kafka. MinIO - официально XFS only для прода (на других ФС работает, но не саппортится). EDB/AWS RDS советуют XFS для Postgres. Рекомендации не из вежливости.
  • Reflinks (с v5). cp --reflink, xfs_io -c "reflink" - мгновенное CoW-копирование файла. Поверх Postgres - pg_upgrade --clone (PG12+) и pg_combinebackup --clone (PG17), поверх контейнеров - overlayfs-style сборка образов. Это «полу-снапшоты»: не subvolume, но отдельные файлы делить блоки умеют.

Note

В исходной версии был pg_basebackup --reflink (PG16+). Такого флага нет: reflink в Postgres используют pg_upgrade --clone и pg_combinebackup --clone.

  • Online grow. xfs_growfs расширяет ФС без размонтирования. Стандартный сценарий «lvextend + xfs_growfs» отработан до автоматизма.
  • Online defrag. xfs_fsr перебирает файлы по фрагментации и переписывает их компактно, не останавливая нагрузку. У ext4 e4defrag тоже есть, но xfs_fsr старше и стабильнее.
  • Reverse-mapping (rmapbt) с v5. Когда диск сообщает «бэд-сектор LBA X», rmapbt мгновенно отвечает «это файл /var/log/foo, offset 4 MiB» - без обхода всей ФС.
  • Quotas - нормальные, без btrfs-style тормозов. Project quotas (по дереву директорий, не только по uid/gid) - фича XFS, которой нет в ext4.
  • DAX. На persistent memory (Optane и подобные) XFS умеет direct access без page cache - read/write идут прямо в NVDIMM. Очень узкая ниша, но единственная нормально работающая.

Плохо

  • Shrink невозможен. Захотел уменьшить ФС - только бэкап + mkfs + restore. Главная причина, по которой ext4 всё ещё используют для root.
  • Не любит memory pressure при fsck. xfs_repair загружает в RAM структуры всей ФС. На больших томах (десятки TiB) может потребоваться 16-64 GiB RAM. Можно -m maxmem или -o bhash=N, но если памяти физически нет - fsck не сделать.
  • Удаление миллионов мелких файлов медленнее ext4. Транзакции в журнале XFS «тяжелее» из-за B+ деревьев и rmapbt.
  • Метаданные журналируются, данные - нет. После crash без fsync файл может оказаться обнулённым (zero-length). Это известно и стандартно (POSIX так и говорит), но первый раз пугает. Лечение - приложение должно делать fsync перед rename().
  • Нет нативного multi-device, нет нативного RAID. Снизу всегда LVM/mdraid. Свои снапшоты XFS не делает, только reflinks по файлам.
  • Дефолтные mount options консервативные. Для прода обычно крутят: noatime, logbsize=256k, allocsize=64k (под БД - наоборот, allocsize=1m и больше), inode64 (давно дефолт, но проверь на legacy).

Грабли

  1. xfs_growfs работает только в сторону роста. Никаких xfs_shrink не существует и не будет.
  2. xfs_repair вне initramfs не запустится для root - нужно single-user/rescue или rebuild.
  3. v4 → v5 апгрейда нет. Только mkfs.xfs и restore.
  4. xfs_quota -x требует mount с -o uquota/gquota/pquota, включить на смонтированной ФС нельзя - нужен remount/umount.
  5. allocsize слишком большой = «дыры» на маленьких файлах и потеря места до flush. Слишком маленький = фрагментация на растущих логах.

Btrfs

Дефолт в openSUSE, Fedora Workstation. Современная CoW ФС.

  • Снапшоты, subvolumes, встроенная компрессия (zstd/lzo/zlib), checksums данных и метаданных, send/receive для инкрементальной репликации, online balance, RAID 0/1/10, dedupe (offline), chattr +C для nodatacow на БД-файлах.
  • RAID 5/6 до сих пор помечен как unstable (write hole). Производительность падает на сильно фрагментированных workloads (БД, VM-образы) без nodatacow. Историческая репутация хрупкости (хотя за последние годы - заметно стабильнее).
  • Фишки: btrfs subvolume snapshot за миллисекунды, compress=zstd:3 бесплатно режет I/O на текстовых данных, Snapper/Timeshift из коробки.

Архитектура: B-tree + CoW

Copy-on-Write (CoW) - фундамент. При изменении блока:

  1. Новый блок пишется в свободное место.
  2. Указатель в дереве обновляется (тоже через CoW - родительский узел перезаписывается на новом месте).
  3. Так вверх до корня дерева.
  4. Корень дерева коммитится атомарно (через superblock update).

Следствия

  • Никаких partial writes. Либо транзакция целиком, либо её нет. Журнал в классическом смысле (как ext4) не нужен.
  • Снапшоты бесплатны - это просто новая ссылка на корень subvolume.
  • Фрагментация - обратная сторона. Случайные записи в большой файл разлетаются по диску.

Хорошо

  • Снапшоты + send/receive. btrfs send -p prev current | ssh backup btrfs receive /backup - инкрементальная репликация на уровне ФС, без rsync-сканирования. Убийственная фича для бэкапов.
  • Прозрачная компрессия. compress=zstd:3 в mount options. zstd:1 почти бесплатен по CPU, на текстах/логах/исходниках экономит 50-70%. Для бинарей/уже сжатых данных Btrfs сам понимает, что жать бесполезно (heuristic), и пропускает.
  • Reflinks. cp --reflink=always - мгновенная CoW-копия. Полезно для VM-образов (golden image → клон за миллисекунды), бэкапов, dev-окружений.
  • Checksums данных и метаданных (crc32c по умолчанию, можно xxhash/sha256/blake2). На multi-device при scrub автоматически чинятся через копию-зеркало. Защита от bitrot - то, чего нет в ext4/XFS.
  • Online всё. Resize (вверх и вниз!), balance (перераспределение чанков), defrag, добавление/удаление устройств - без размонтирования. XFS shrink, кстати, до сих пор невозможен.
  • Гибкие RAID-профили на уровне чанков, меняются на ходу: btrfs balance start -dconvert=raid1 -mconvert=raid1 /mnt.
  • Quotas через qgroups, по subvolume. Но: исторически глючные и тормозящие при больших объёмах. С simple quotas (kernel 6.7+) стало лучше.

Плохо

  • RAID 5/6 - broken by design до сих пор. Write hole не закрыта. На вики Btrfs прямым текстом: «unstable, do not use for valuable data». Для parity-RAID - ZFS или mdraid под Btrfs.
  • Производительность на БД-workload. Без nodatacow (+C) фрагментация съедает throughput. С +C - нет checksums, нет компрессии. Так себе trade-off для prod-БД. ZFS на таком же сценарии ведёт себя лучше (recordsize tuning).
  • Quota groups + большие FS = тормоза. Включённые qgroups могут заметно замедлять btrfs balance и удаление снапшотов.
  • ENOSPC-сюрпризы. Btrfs может сказать «нет места» при свободных гигабайтах, потому что чанки уже выделены под data, а metadata некуда. Лечится btrfs balance start -dusage=50. Современные ядра справляются лучше, но артефакт остался.
  • Восстановление после катастрофы. btrfs check --repair - last resort, может сделать хуже. Best practice - бэкапы и btrfs restore для вытаскивания данных. У ext4 e2fsck в этом плане куда дружелюбнее.
  • Metadata-heavy операции (rm -rf огромного дерева, find /) медленнее ext4/XFS. CoW + множественные деревья дают оверхед.

Грабли

  1. ENOSPC при свободном месте. Btrfs аллоцирует диск чанками (1 GiB для data, 256 MiB для metadata). Если все чанки расписаны под data, а metadata-чанк заполнился - записать новый файл некуда: для него нужна запись в metadata-tree.
  2. df врёт, и это by design. Используй btrfs filesystem usage / btrfs filesystem df.
  3. Снапшоты - не бесплатны в долгую. Старые снапшоты держат старые блоки, free space постепенно тает.
  4. Quota groups (qgroups) - исторический ад. До simple quotas (6.7+) - best effort стратегия «не включать».
  5. Восстановление после повреждения - стресс. План - бэкапы + btrfs restore, не btrfs check --repair.
  6. Поведение под нехваткой памяти. На тесных по RAM системах CoW + B-tree commit'ы могут вести себя непредсказуемо.

ZFS

Порт из Solaris, лицензия CDDL (поэтому не в mainline kernel).

  • Всё что у Btrfs + рабочий RAID-Z1/2/3, ARC/L2ARC (кэш в RAM + SSD), ZIL/SLOG, native encryption, send/receive, дедупликация (но прожорливая по RAM), снапшоты с zero overhead.
  • Лицензионная несовместимость с GPL - ставится через DKMS, ломается при обновлении ядра. Прожорлив по RAM (~1 GiB на 1 TiB при включённой dedupe - больше). Vdev нельзя расширить добавлением одного диска (хотя RAID-Z expansion появился в OpenZFS 2.3, январь 2025).
  • Фишки: «правильный» enterprise-grade, считается золотым стандартом для NAS/storage. TrueNAS, Proxmox, Ubuntu offer root-on-ZFS.

Архитектура: pool → vdev → dataset, CoW + Merkle-tree

ZFS - это не «ФС», а интегрированный stack: volume manager (как LVM) + RAID (как mdraid) + filesystem в одном. Layering нет принципиально: пул знает про диски, ФС знает про блоки, всё видит друг друга и принимает решения вместе.

Структура снизу вверх:

  • Физические диски объединяются в vdev (virtual device): mirror, raidz1/2/3, draid, single. Vdev
  • это unit of redundancy.
  • Несколько vdev объединяются в zpool. Запись страйпится по всем vdev пула (как RAID-0 поверх RAID-Z). Добавление vdev в пул расширяет ёмкость без перестройки.
  • Внутри пула создаются datasets - либо файловые системы (ZFS-FS, монтируются как любая ФС), либо zvol (блочные устройства для iSCSI/VM-дисков).
  • Снапшоты и клоны - на уровне dataset. send/receive - между dataset'ами.

Запись - CoW + transaction groups (TXG). Изменения копятся в RAM (open TXG), раз в несколько секунд (txg_timeout, по умолчанию 5s) коммитятся атомарно: новые блоки записаны, uberblock (корень) обновлён в одном из 128 ring-slot'ов. До коммита sync write'ы идут в ZIL (ZFS Intent Log) - отдельный лог для durability fsync().

Merkle-tree: каждый блок ссылается на дочерние через указатель + checksum. Поэтому ZFS обнаруживает silent corruption на любом уровне - от данных до метаданных до uberblock.

ARC (Adaptive Replacement Cache) - кэш в RAM, умнее Linux page cache: учитывает и recency, и frequency, не вымывается одним sequential scan'ом. L2ARC - расширение ARC на SSD. SLOG - отдельное устройство для ZIL (NVMe/Optane), ускоряет fsync-нагрузки.

Следствия

  • Storage stack единый, без зазоров. mdraid не знает что выше ФС, ФС не знает что снизу RAID - отсюда write hole в RAID-5. ZFS знает всё. Поэтому RAID-Z не имеет write hole: parity и data пишутся в одной транзакции, либо обе, либо ни одной.
  • Снапшоты бесплатны и мгновенны. Это просто ссылка на старый uberblock: пока новые блоки CoW-копируются, старые не удаляются.
  • send/receive передаёт diff между двумя снапшотами потоком. Инкрементальный бэкап на удалённый pool
  • одна команда, без rsync-сканирования.
  • Память - лекарство и яд. ARC по умолчанию забирает до 50% RAM (на FreeBSD - больше). На сервере с 8 GiB и нагруженным Postgres это конкуренция между ARC и shared_buffers, нужно крутить zfs_arc_max.

Хорошо

  • Надёжный parity-RAID. RAID-Z1/2/3 (1/2/3 диска под parity), draid (для очень больших массивов с distributed spare), mirror. В отличие от Btrfs RAID-5/6, write hole закрыта by design. Причина, по которой ZFS - стандарт для NAS/архивных хранилищ.
  • Send/receive с шифрованием. zfs send -w отправляет уже зашифрованные блоки без расшифровки на отправляющей стороне - приёмник не видит ключи. Идеальный off-site backup на untrusted машину.
  • Native encryption per-dataset. zfs create -o encryption=on -o keyformat=passphrase. Ключи можно хранить в файле/KMS, загружать lazy при первом доступе.
  • ARC. На read-heavy нагрузке ARC бьёт Linux page cache: за счёт adaptive replacement не вымывается sequential I/O (одного find / достаточно, чтобы page cache забыл всё нужное, а ARC - нет).
  • Recordsize per-dataset. Для Postgres ставят 8K (= размер страницы), для Kafka сегментов - 1M, для логов/архивов - 1M с компрессией. Редкий уровень контроля.
  • Compression by default. lz4 включают почти всегда - почти бесплатен по CPU, на текстах сильно экономит I/O. zstd-3/9 - для архивных dataset'ов.
  • Scrub. Раз в неделю/месяц обходит весь пул, проверяет checksums, чинит из mirror/parity. Bitrot обнаруживается ДО того, как ты захочешь прочитать файл.
  • Снапшоты + холды. zfs hold предотвращает удаление снапшота, пока он удерживается (например, идёт send). Никаких «удалил снапшот пока шёл бэкап».
  • Self-healing. Прочитал блок с диска - checksum не сошёлся - взял с зеркала/parity, отдал приложению, переписал плохой блок. Прозрачно для приложения.
  • zvol для VM-дисков. Снапшот, клон, send/receive - поверх обычного блочного устройства. Альтернатива qcow2 + LVM thin.

Плохо

  • Лицензия CDDL. Несовместима с GPL2 ядра Linux - поэтому ZFS не может попасть в mainline. Распространяется как out-of-tree модуль (OpenZFS) через DKMS. При апгрейде ядра модуль пересобирается. Если новое ядро ломает API (а это случается раз в 2-3 релиза мажоров) - апгрейд откладывается на 2-8 недель, пока выйдет новый OpenZFS.
  • Прожорлив по RAM. ARC на 50% RAM по умолчанию - не баг, by design. На 4-8 GiB машинах ZFS уже неуютно. С dedup совсем плохо: dedup-таблица сидит в ARC, ~5 GiB RAM на 1 TiB уникальных данных. Поэтому dedup в ZFS выключают чаще, чем включают.
  • Vdev неэластичный. Долго (до 2024) единственный способ расширить пул - добавить новый vdev (то есть ещё одну группу дисков). RAID-Z expansion (добавление одного диска в существующий vdev) появилось в OpenZFS 2.3 в январе 2025 - фича сырая, восстанавливается медленно, не убирает старый stripe-pattern.
  • Нельзя удалить vdev. Mirror убрать можно, top-level vdev - только если пул mirror-only (zpool remove). Для raidz remove не поддерживается. Ошибся на mkfs - пересоздавать пул.
  • Поведение под memory pressure хуже, чем у нативных ФС ядра. ARC долго отдаёт память обратно kernel'у, OOM-killer может пристрелить процесс, который мог бы и пожить.
  • Setup сложнее. Установить ZFS на root в Ubuntu - отдельный квест с initramfs и zfs-mount.service. Любая Linux-распределённость, кроме TrueNAS/Proxmox/Ubuntu, - это «соберите сами».
  • Не любит overcommit. zvol с volsize больше, чем свободно в пуле, можно создать через sparse - но при заполнении гость отвалится без warning. У ext4/XFS поверх LVM thin - то же самое, просто там это привычнее.
  • fsync дорогой без SLOG. Sync write идёт в ZIL (фактически - двойная запись), пока не закоммитится TXG. На обычных SSD терпимо, на HDD без SLOG - катастрофа для Postgres.

Грабли

  1. zpool import после reboot может потребовать -f, если pool был «not cleanly exported». Стандартная история на нештатном shutdown.
  2. Снапшот zvol съедает место - даже без записей, потому что любая запись в активную копию начинает плодить CoW-копии старых блоков.
  3. dedup включил → выключить нельзя. Только пересоздание пула. zfs set dedup=off отключает ТОЛЬКО для НОВЫХ записей, старые dedup-blocks остаются и сидят в DDT.
  4. ashift задаётся при создании vdev и не меняется. Поставил 9 (512b) на диск с 4K-сектором - потерял производительность навсегда. Стандарт сегодня - ashift=12.
  5. ARC на сервере с БД - крутить zfs_arc_max (/etc/modprobe.d/zfs.conf: options zfs zfs_arc_max=8589934592 для 8 GiB).
  6. send/receive обрывается → recv state остаётся, надо zfs receive -A для abort.
  7. Перевод pool на новую версию OpenZFS - односторонний. zpool upgrade сделал → на старой версии этот pool уже не импортируешь.

bcachefs

Была в mainline с ядра 6.7 (2024) по 6.17, теперь ставится отдельным модулем. Молодая, но амбициозная.

  • CoW, checksums, компрессия, шифрование, многоуровневое хранилище (tiered storage: NVMe + HDD в одном пуле с автоматической миграцией), erasure coding, replicas.
  • Сырая, в проде использовать рано. Из-за конфликтов автора (Kent Overstreet) с Линусом удалена из mainline, живёт out-of-tree через DKMS.
  • Фишка: настоящий tiered storage без сторонних инструментов (типа bcache+LVM).

Архитектура: эволюция из bcache, B-tree + CoW

bcachefs выросла из bcache - block-level кэша SSD-перед-HDD, который Kent Overstreet вёл с 2010. К 2015 стало ясно, что инфраструктура bcache (CoW B-tree, журнал, allocator) достаточно мощная, чтобы стать полноценной ФС - так появилась bcachefs. В mainline принята с 6.7 (январь 2024) со статусом experimental.

Цель - собрать в одной ФС всё лучшее: надёжность ZFS, фичи Btrfs, скорость ext4/XFS. И tiered storage из bcache как killer feature.

Внутри - CoW B-tree (как Btrfs), но дерево одно глобальное (а не лес как у Btrfs), что упрощает целостность и снижает overhead на mount. Журнал отдельный (а не сам B-tree как у ZFS) - для durability fsync без write amplification CoW-коммита.

Multi-device встроено. Каждое устройство имеет target label (foreground, background, promote, metadata). При записи блок попадает на foreground (быстрый NVMe), фоном мигрирует на background (медленный HDD). При чтении промоутится обратно. Это и есть tiered storage - то, что в Linux раньше делали bcache + LVM + ручной хореографией.

Replication и erasure coding - на уровне ФС, не блочного устройства. replicas=2 = «храни 2 копии», как ZFS mirror. erasure_code= на больших write'ах - RAID-5-подобная избыточность с N data + M parity. По заявлениям автора, write hole закрыта (в отличие от Btrfs RAID-5/6), в проде это пока никто массово не проверял.

Snapshots и subvolumes - есть, но реализация моложе чем у Btrfs/ZFS.

Следствия

  • Tiered storage без слоёв. Один формат данных от NVMe до HDD, без перекладывания через bcache/LVM/dm-cache. Это уникально для Linux.
  • Молодость = баги. На 2024-2025 регулярно фиксят корректность, не производительность. Никто из вендоров (RHEL, SUSE, Ubuntu) bcachefs официально не саппортит.
  • Toolchain тонкий. bcachefs-tools есть, но возможностей repair заметно меньше, чем у e2fsck/xfs_repair/btrfs check.

Хорошо

  • Tiered storage из коробки. bcachefs format --label=ssd.ssd1 /dev/nvme0n1 --label=hdd.hdd1 /dev/sda --foreground_target=ssd --background_target=hdd --promote_target=ssd создаёт ФС, где горячие данные сами едут на NVMe, холодные - на HDD, прозрачно для приложения. В одной команде то, на что в bcache+LVM уходит полдня.
  • Erasure coding с надеждой на отсутствие write hole. Если выстрелит - первая нативно-Linux'овая parity-ФС без проблем Btrfs RAID-5/6 и без out-of-tree статуса ZFS.
  • Чистая архитектура. Один B-tree, явный журнал, понятные структуры. Внутренности проще читать, чем Btrfs/ZFS.
  • Per-file/per-directory параметры. Компрессия, checksum-алгоритм, replicas, target можно задать на конкретный файл/подкаталог (xattr), а не только на весь mount.
  • Активная разработка. Фичи добавляются регулярно, фидбек с продакшен-пилотов учитывается.

Плохо

  • Удалена из mainline. Конфликт Kent Overstreet с Линусом и другими мейнтейнерами обострился в 2024-2025 (Kent присылал крупные изменения вне merge window и не соглашался с процессом). В 6.17 ядро пометило bcachefs как externally maintained, в 6.18 код удалили. Теперь это out-of-tree модуль через DKMS - ZFS-уровень головной боли при обновлении ядра, но без enterprise-поддержки.
  • Сырой repair. bcachefs fsck умеет основные сценарии, но на углах ловит баги. Единый advice от мейнтейнеров - «делайте бэкапы», а не «чините». Нормально для experimental, но в проде неприемлемо.
  • Нет официальной поддержки от дистрибутивов. RHEL - нет и не планируется. Ubuntu - есть пакет bcachefs-tools, но без commercial support. SUSE - экспериментально.
  • Производительность ещё не настроена. На синтетике bcachefs местами сравним с XFS/ext4, местами
  • заметно медленнее. Авторские бенчмарки красивые, независимые - разброс.
  • Документация ниже среднего. Большая часть знаний в mailing list, commit messages, и личных постах Kent'а.
  • Совместимость on-disk формата ломалась несколько раз за 2023-2025. Документировано (experimental), но при апгрейде ядра - readme + tools нужно читать.

Грабли

  1. Не ставить на root, не ставить на критичные данные. До stable-статуса в апстриме - это playground.
  2. Бэкап на ext4/XFS + restore - план B по умолчанию.
  3. Версия bcachefs-tools должна соответствовать версии ядра. Стащил tools поновее - на старом ядре mount может отказать с unknown features.
  4. На multi-device пуле потеря «фонового» (HDD) устройства = потеря холодных данных, если replicas=1. По умолчанию replicas=1. Сюрприз для тех, кто ждал ZFS-семантики.
  5. Compression-эвристики моложе Btrfs/ZFS - на mixed-content томах иногда жмёт уже сжатое.

Когда брать

  • Домашний NAS с NVMe-кэшем и HDD-массивом, и не страшно потерять данные. Лучшее, что есть в Linux для этого сценария.
  • Эксперименты, разработка, тесты - feedback автору всегда полезен.
  • Под прод - не сейчас. Минимум - дождаться, пока статус сменится с experimental и появится хотя бы один дистрибутив с коммерческим саппортом.

Сводная таблица

Требование ext4 XFS Btrfs ZFS mdraid+LVM+XFS
Resize ↑ online online online autoexpand online
Resize ↓ offline никогда online только через destroy для ext4 LV
Добавить диск нужен LVM/RAID снизу нужен LVM/RAID снизу btrfs device add zpool add mdadm --add
RAID нативно нет нет только 0/1/10 (5/6 broken) RAID-Z1/2/3, mirrors всё через mdraid
Бэкап БД (Postgres и др.) только внешние тулзы reflinks + pgBackRest нужен +C, теряет фичи snapshots/send thin snapshots + pgBackRest
Скорость PG/Kafka/MinIO хорошо отлично (офиц. реком.) плохо: фрагментация требует тюнинга отлично
Snapshots нет нет (только reflinks) native native через LVM thin
Checksums данных нет нет да да нет
Компрессия нет нет zstd lz4/zstd нет
Mainline kernel да да да нет, DKMS да
RAM требования низкие низкие средние высокие (≥8 GB) низкие
MinIO supported warn официально нет нет да
Kafka рекомендация ок официально (Confluent) нет warn да
Postgres рекомендация ок официально (EDB/AWS) нет без +C warn, с тюнингом да
Сложность setup низкая низкая средняя средняя средняя
Сложность восстановления e2fsck xfs_repair часто = restore from backup ZFS-специфика стандартные тулзы

Итого: ставь то, что умеешь восстанавливать.

  • root - ext4
  • БД и Kafka - XFS поверх LVM
  • NAS - ZFS
  • домашний NAS с NVMe-кэшем - bcachefs, если не жалко данных
  • Btrfs - только если CoW-фичи реально нужны и nodatacow на горячих файлах не пугает