Что такое Copy-on-Write и почему это меняет правила игры
Copy-on-Write (CoW, копирование при записи) определяет момент, когда данные попадают на диск. Файловая система не перезаписывает существующий блок, а пишет новую версию в свободное место и затем атомарно переключает указатель в метаданных. Пока транзакция не зафиксирована, на диске лежат обе версии, поэтому сбой питания посреди записи не оставляет файл в полусостоянии. ZFS фиксирует такие транзакции группами (txg), Btrfs обновляет CoW B-дерево.
ext4 и XFS работают иначе: изменённые блоки пишутся поверх старых, а целостность после сбоя обеспечивает журнал. ext4 по умолчанию использует режим data=ordered, XFS ведёт журнал метаданных. Журнал защищает структуры и частично данные, но сама перезапись остаётся разрушительной: прежнее содержимое блока исчезает.
Короткий ответ: CoW-файловые системы выбирают там, где нужны мгновенные снапшоты, проверка целостности блоков и версионирование, то есть на NAS, серверах виртуализации и файловых хранилищах. ext4 и XFS остаются рациональным выбором для простых серверов, инсталляций с малым объёмом RAM и высоконагруженных СУБД, где фрагментация и задержки важнее снапшотов.
Числовые ориентиры ниже даны как диапазоны планирования, а не как жёсткие нормативы: требования зависят от версии OpenZFS или ядра Linux, размера блока, профиля нагрузки и объёма метаданных. КоW-файловая система меняет не только способ записи, но и требования к железу, поэтому сравнение имеет смысл вести по конкретному сценарию.
Мгновенные снапшоты: как CoW делает их бесплатными
Снапшот в CoW-ФС - ссылка на зафиксированное состояние дерева метаданных. Данные при этом не копируются: система запоминает, какие блоки принадлежат этому состоянию. Создание снапшота датасета на 1 ТБ занимает секунды и изначально расходует килобайты под служебные структуры.
Место начинает расти после изменений. Перезаписанный блок нельзя тронуть, пока на него ссылается снапшот, поэтому новая версия ложится рядом, а старая остаётся в снапшоте. Чем активнее запись и чем дольше хранятся снапшоты, тем больше места они удерживают. Удаление снапшота освобождает только те блоки, на которые больше никто не ссылается.
Рабочая схема на NAS: снапшот каждые 15 минут, срок хранения 30 дней. При интенсивной записи такой набор занимает заметную долю пула, поэтому за расходом следят через свойства usedbysnapshots в ZFS или btrfs filesystem usage. Отдельный файл из снапшота достают через каталог .zfs/snapshot, откат всего датасета делают командой zfs rollback.
В ext4 и XFS аналога на уровне файловой системы нет. Снапшоты делают через LVM на тонких томах или сторонние механизмы, и это уже уровень менеджера томов: снапшот LVM отслеживает изменённые экстенты и требует отдельного планирования места. XFS при включённом reflink умеет клонировать отдельные файлы с разделением блоков, но снапшотов тома не даёт.
Дедупликация и контрольные суммы: надёжность против ресурсов
Контрольные суммы ZFS считает для каждого блока данных и метаданных и проверяет при каждом чтении. При наличии избыточности (mirror, RAID-Z) повреждённый блок восстанавливается из копии или чётности, а событие фиксируется в zpool status. Btrfs делает то же через checksum-деревья и команду btrfs scrub. Так ловится bit rot, который журналируемые ФС замечают только на уровне своих структур: ext4 с metadata_csum и XFS v5 проверяют метаданные, а не пользовательские данные.
Дедупликация выглядит привлекательно и редко окупается. В ZFS таблица дедупликации (DDT) живёт в оперативной памяти, и на практике закладывают примерно 1-5 ГБ на каждый терабайт данных в зависимости от размера блока и настроек. При 10 ТБ и 16 ГБ RAM включение dedup приводит к нехватке памяти и падению скорости, поэтому дедупликацию чаще отключают, а экономию получают сжатием (lz4, zstd).
В Btrfs штатной inline-дедупликации нет: применяют внешние инструменты вроде duperemove или bees, которые проходят по данным и пакетно (band-based) объединяют совпадающие экстенты. Памяти это требует меньше, чем DDT, но эффект даёт только на повторяющихся данных: резервных копиях, шаблонах ВМ, слоях контейнеров.
ZFS и Btrfs: сравнение двух CoW-гигантов
ZFS пришла из Solaris, на Linux доступна через проект OpenZFS и ставится либо из репозитория дистрибутива, либо отдельным DKMS-модулем. Btrfs входит в ядро Linux и доступна сразу после установки системы. Архитектурная разница заметна с первых дней работы: ZFS оперирует пулом и vdev с общим кэшем ARC, Btrfs собирает набор устройств и хранит данные в CoW B-деревьях с subvolume.
Надёжность и целостность данных: у кого больше гарантий
ZFS использует сквозные контрольные суммы, атомарные транзакции и уровни избыточности RAID-Z1, RAID-Z2, RAID-Z3, а также зеркала. Схема с копированием при записи и чётностью избавляет RAID-Z от проблемы write hole, характерной для классического parity RAID. Btrfs тоже считает контрольные суммы и умеет scrub, но RAID 5/6 в её документации долго помечался как нестабильный из-за того же write hole; для продакшена рекомендуют RAID1, RAID1C3 или RAID10.
ECC-память для ZFS считается желательной: ошибка в RAM может привести к записи блока с корректной с виду контрольной суммой. Обязательным требованием ECC не является, но при её отсутствии растёт цена ошибки, и тогда важнее регулярный scrub, мониторинг SMART и чтение логов.
Показательны две готовые платформы с разными подходами. TrueNAS строит хранилище на ZFS целиком, включая снапшоты, репликацию и проверку целостности. Synology размещает Btrfs поверх mdraid: чётность считает mdraid, а Btrfs отвечает за контрольные суммы, subvolume и снапшоты общих папок.
Потребление оперативной памяти: сколько нужно на самом деле
Кэш ARC в ZFS по умолчанию занимает примерно половину доступной памяти, но его размер ограничивается параметром zfs_arc_max. Кэш можно урезать без потери данных, а вот таблица дедупликации требует резидентной памяти, и это главный аргумент против dedup на домашних и малых серверах. В свежих версиях OpenZFS DDT можно вынести на быстрый special vdev, что снижает давление на RAM, но добавляет требования к дискам.
Btrfs менее требовательна: для небольших наборов данных хватает 2 ГБ, но снапшоты, балансировка и дедупликация внешними инструментами увеличивают расход. ext4 и XFS практически не требуют памяти сверх файлового кэша страниц.
| Файловая система | Снапшоты | Контрольные суммы данных | Дедупликация | Ориентир по RAM | Расширение массива |
|---|---|---|---|---|---|
| ZFS | мгновенные, на уровне датасета | все блоки данных и метаданных | встроенная, DDT в памяти | от 4 ГБ, комфортно 8-16 ГБ и больше | новый vdev; расширение RAID-Z появилось в свежих версиях OpenZFS |
| Btrfs | мгновенные, на уровне subvolume | все блоки данных и метаданных | внешними инструментами | от 2 ГБ для простых наборов | добавление дисков по одному |
| ext4 | через LVM | метаданные (metadata_csum) | нет | без особых требований | рост раздела, LVM |
| XFS | через LVM; reflink для отдельных файлов | метаданные (v5) | утилитами при включённом reflink | без особых требований | xfs_growfs |
Сложность эксплуатации: что нужно знать перед переходом
В ZFS повседневные операции выглядят так: zpool status показывает состояние устройств и ошибки, zpool scrub запускает проверку целостности, zfs list -t snapshot перечисляет снапшоты, zfs send и zfs receive переносят датасеты на резервный сервер целиком или инкрементально. Пул нельзя заполнять выше примерно 80%: при остатке свободного места меньше 10% метаданные и новые блоки размещаются хуже, а фрагментация растёт. Добавить один диск внутрь существующего RAID-Z vdev исторически нельзя, расширение RAID-Z появилось только в свежих версиях OpenZFS, и по-прежнему нормальный путь роста - новый vdev целиком.
В Btrfs операции другие: btrfs subvolume snapshot создаёт снапшот, btrfs send и btrfs receive переносят данные, btrfs scrub start проверяет целостность, btrfs balance перераспределяет блоки. Диски добавляются по одному, что удобно для домашних NAS. Обратная сторона - балансировка может идти часами и грузить диски, а нехватка места под метаданные даёт ошибку no space left при формально свободном месте; лечится балансом с фильтром по метаданным, btrfs balance start -musage=10.
Обе CoW-ФС требуют регулярного scrub и мониторинга, а не «поставил и забыл». ext4 и XFS дешевле в обслуживании: fsck и xfs_repair запускаются редко, дополнительных процедур проверки целостности блоков нет. Дополнительные настройки ZFS и TrueNAS разобраны в отдельном практическом руководстве по развёртыванию.
CoW против традиционных ФС: ext4 и XFS в сравнении
ext4 остаётся стандартом по умолчанию в большинстве дистрибутивов: журналирование, экстенты, отложенное выделение блоков, контрольные суммы метаданных. XFS выигрывает на больших файлах и многопоточной записи благодаря группам размещения и B-деревьям, поддерживает онлайн-дефрагментацию xfs_fsr и reflink. Ни одна из них не даёт снапшотов тома и не проверяет контрольными суммами сами данные.
Производительность и фрагментация: где CoW буксует
Фрагментация в CoW-ФС возникает из-за самого принципа: новые блоки ложатся в свободные места, и последовательный файл со временем разбивается на части. На HDD это добавляет перемещения головок и снижает скорость последовательного чтения, на SSD эффект мягче, но растёт объём служебных операций внутри накопителя. Сильнее всего страдают базы данных и образы виртуальных машин при долгой случайной записи.
Инструменты борьбы ограничены. В Btrfs есть опция монтирования autodefrag, но для образов ВМ и СУБД она не подходит: лишние перезаписи вредят больше, чем помогают. В ZFS встроенной дефрагментации нет, помогает перезапись данных (копирование датасета или файла заново) либо пересоздание датасета на освобождённом пуле. XFS умеет онлайн-дефрагментацию командой xfs_fsr, а ext4 и XFS лучше сохраняют последовательность файлов стратегиями размещения.
На SSD важен TRIM: fstrim.timer в systemd-дистрибутивах для ext4, XFS и Btrfs, zpool trim pool или опция autotrim=on для ZFS. Без TRIM накопитель со временем теряет в скорости записи. Как измерить разницу до и после смены файловой системы, описано в материале о методике тестов производительности.
Когда ext4 или XFS всё ещё лучший выбор
- Малый объём памяти: сервер с 2-4 ГБ RAM и базой данных на 1 ТБ. ARC заберёт большую часть доступной памяти, приложению останется минимум, ext4 или XFS работают предсказуемее.
- Простой веб-сервер или файловый обмен без версионирования: снапшоты не нужны, а накладные расходы на CoW и обслуживание остаются.
- СУБД с интенсивными fsync и случайной записью: ext4 или XFS на выделенном NVMe дают более ровные задержки, чем CoW с фрагментацией.
- Однодисковые системы и старые платформы: преимущества RAID-Z и checksums не раскрываются, а OpenZFS из DKMS-модуля может не пережить обновление ядра.
- Нужны простые операции роста и восстановления: xfs_growfs, resize2fs и минимальный набор процедур обслуживания.
Общее правило простое: CoW даёт выигрыш в защите данных и гибкости, ext4 и XFS - в предсказуемости записи и скромных требованиях к железу. Обзор сценариев для систем хранения сведён в материале о выборе ZFS, XFS и Btrfs для СХД.
Реальные кейсы: когда CoW-ФС оправдана, а когда создаёт проблемы
Ниже типовые конфигурации, которые встречаются при проектировании серверов и NAS. Цифры даны как ориентиры планирования, а не как результат единого замера: перед повторением любой схемы проверяйте её на своём наборе данных.
Кейс: NAS на TrueNAS с ZFS для защиты от ransomware
Конфигурация: 6 HDD в RAID-Z2, 32 ГБ RAM, отдельный SSD под системный датасет, снапшоты каждые 15 минут с хранением 30 дней, дедупликация выключена, сжатие lz4. Снапшоты дают защиту от шифрования: после атаки датасет откатывают к состоянию до появления зашифрованных файлов, а копии уезжают на второй сервер инкрементальным zfs send. Дедупликация выключена осознанно: DDT на десяток терабайт съел бы память, тогда как сжатие даёт экономию без постоянного расхода RAM. Что учесть: снапшоты удерживают удалённые файлы, поэтому usedbysnapshots контролируют, а схему ретенции пересматривают при росте нагрузки.
Кейс: сервер виртуализации на Proxmox с ZFS
Конфигурация: пул зеркал на NVMe под образы ВМ, 32 ГБ RAM, ARC ограничен половиной памяти, SLOG на отдельном NVMe для синхронных записей NFS и iSCSI, блок zvol или датасет с размером блока 8-16 КБ под случайную нагрузку. Снапшоты ВМ перед обновлениями занимают секунды, откат дешевле восстановления из полной копии. Инкрементальная репликация zfs send -i переносит только изменённые блоки. Что учесть: опция sync=disabled ускоряет запись заметно, но при сбое питания теряются последние секунды данных, поэтому для баз данных и NFS её применяют осознанно и с журналом на SLOG. Со временем образы ВМ фрагментируются, и это отражается на задержках.
Кейс: Synology с Btrfs и снапшотами общих папок
Конфигурация: Btrfs развёрнута поверх mdraid, чётность считает mdraid, а Btrfs отвечает за контрольные суммы, subvolume и снапшоты общих папок по расписанию. RAID 5 и 6 на самом Btrfs в такой схеме не применяют: parity-режимы Btrfs остаются рискованными из-за write hole. Снапшоты закрывают случайное удаление и часть сценариев с шифровальщиками, репликация отправляет копии на второе устройство. Что учесть: scrub и балансировку ставят в расписание, а за свободным местом для метаданных следят отдельно, иначе появляется ошибка нехватки места при визуально свободном томе. Разница между файловым и блочным доступом на таких системах разобрана в статье об архитектуре NAS.
Кейс: PostgreSQL на ext4 или XFS
Конфигурация: выделенный NVMe, ext4 с data=ordered либо XFS с включённым reflink, WAL на том же быстром носителе, регулярная проверка задержек через iostat. СУБД с интенсивными fsync и случайной записью выигрывает от предсказуемости: CoW добавляет запись новой версии блока и обновление дерева, а фрагментация усиливает хвосты задержек. Если отказываться от CoW не хочется, ZFS тоже применяют, но с настройками: recordsize 8-16 КБ, logbias=throughput, SLOG на NVMe и запас RAM под ARC. Сравнение накопителей и готовые сценарии тестов для СУБД собраны в материале о производительности дисковых подсистем.
Чек-лист: стоит ли переходить на CoW-файловую систему
- Нужны ли мгновенные снапшоты и откаты к точке во времени? Если да, CoW даёт их без копирования данных. Если достаточно ежедневного бэкапа, преимущество теряется.
- Требуется ли проверка целостности самих данных? ZFS и Btrfs считают контрольные суммы блоков и лечат bit rot при наличии избыточности. ext4 и XFS проверяют только метаданные.
- Сколько RAM готовы выделить? Ориентиры: ZFS от 4 ГБ, комфортно 8-16 ГБ и больше; Btrfs от 2 ГБ для простых наборов; ext4 и XFS почти без накладных расходов.
- Есть ли ECC-память? Для ZFS она желательна, но не обязательна. Без ECC обязательно настройте scrub по расписанию и мониторинг SMART.
- Действительно ли нужна дедупликация? Для ZFS планируйте примерно 1-5 ГБ RAM на терабайт данных. Чаще выгоднее сжатие zstd или lz4.
- Какой профиль нагрузки? NAS, файловый сервер, виртуализация: CoW уместна. СУБД с интенсивными fsync: ext4 или XFS, либо тщательно настроенный ZFS на NVMe.
- Какие носители используются? На HDD фрагментация CoW заметнее, на SSD и NVMe включайте TRIM: fstrim.timer, zpool trim, autotrim=on.
- Готовы ли запускать scrub по расписанию? zpool scrub в ZFS и btrfs scrub start в Btrfs. Отчёты об ошибках нужно читать, а не откладывать.
- Как будете расширять массив? Добавление дисков по одному удобнее в Btrfs, рост через новый vdev - в ZFS.
- Готовы ли установить zfs_arc_max? Ограничение ARC освобождает память приложениям, но уменьшает кэш чтения. Значение подбирают по фактическому потреблению.
- Есть ли план миграции и окно отката? Проверьте объём, перенесите данные через rsync с проверкой контрольных сумм или zfs send с приёмом на новом пуле и сохраните исходную ФС до подтверждения результата.
- Есть ли резервная копия вне массива? Снапшоты не заменяют бэкап: сбой пула уносит и данные, и снапшоты. Работает схема 3-2-1 с периодической проверкой восстановления.
- Проверена ли конфигурация на стенде? Прогоните fio до и после, снимите iostat, посмотрите ARC hit ratio, фрагментацию через zpool list -v и btrfs filesystem df. Решение принимайте по своим цифрам, а не по общим рекомендациям.
Если ответы на пункты про снапшоты, целостность данных и объём RAM совпадают с возможностями CoW-ФС, переход оправдан. Если сомнения вызывает железо, профиль нагрузки или отсутствие бэкапа вне массива, оставайтесь на ext4 или XFS и вернитесь к вопросу после тестового стенда: разверните один пул или subvolume, перенесите копию рабочих данных, замерьте задержки и только затем планируйте миграцию продакшена.