# ext4 - рабочая лошадь Linux-ФС _Файловая система · LinuxLab Knowledge Base_ **TL;DR:** ext4 - дефолтная ФС большинства дистро: журналирование, extents, фиксированное число inode при mkfs. Главные тюны - data-mode, noatime, lazy init. Стабилен 15+ лет. Не масштабируется как XFS. ## Зачем именно ext4 ext4 - **default** на Debian/Ubuntu/Linux Mint/Arch-based и многих других. Хорошо изучен, инструментарий вырос за 15 лет, recovery-кейсов больше всего. По сравнению с предшественниками: | Версия | Что добавила | |--------|--------------| | ext2 (1993) | базовая ФС | | ext3 (2001) | journaling | | ext4 (2008) | extents, 1 EiB ФС, 16 TiB файлы, online defrag, multi-block alloc | Если задача "поставить любую ФС и забыть" - ext4. Если у тебя миллионы мелких файлов или один файл на терабайт - смотри на [xfs](/kb/xfs.md) или [btrfs](/kb/btrfs.md). ## Журналирование Главное отличие от ext2 - **journal** (журнал). Когда меняется метаданные ([inode](/kb/inode.md)/директории/bitmap), сначала пишется план изменений в кольцевой журнал, потом сами изменения. Краш до commit'а журнала - откатываемся, после - дочитываем журнал и применяем. Три режима, выбираются `mount -o data=...`: | Режим | Что журналируется | Когда | |-------|-------------------|-------| | `data=writeback` | только метаданные; данные могут попасть на диск ДО или ПОСЛЕ метаданных | максимальная скорость, риск "файл указывает на чужие блоки" после краша | | `data=ordered` (default) | метаданные после fsync данных | компромисс: метаданные согласованы с данными | | `data=journal` | и метаданные, и данные через журнал | максимальная безопасность, медленнее в 2x | Для БД иногда выгодно `data=writeback` + WAL приложения берёт на себя crash-safety. Для контейнерного хоста - default. Журнал лежит **на той же ФС** в специальном inode (8). Можно вынести на отдельный быстрый диск: ```bash mke2fs -O journal_dev /dev/nvme0n1 mke2fs -t ext4 -J device=/dev/nvme0n1 /dev/sda1 ``` ## Inode density - **неизменяемая** характеристика При `mkfs.ext4` определяется **число inode** = размер_ФС / `bytes-per-inode`. Default - 1 inode на 16 KiB. На 1 TiB ФС это ~67M inode'ов, по умолчанию. Что важно: **нельзя добавить inode'ов после mkfs**. `df -i` покажет использование. Если уперлись в 100% inode при свободных гигабайтах - только пересоздать ФС. Для систем с **миллионами мелких файлов** (mail-spool, кэш) - повышай плотность: ```bash # 1 inode на 4 KiB - в 4 раза больше mkfs.ext4 -i 4096 /dev/sdb1 # Или через профиль из /etc/mke2fs.conf mkfs.ext4 -T news /dev/sdb1 ``` Для гигантских файлов (видео, бэкапы) - уменьшай (`-i 65536`), экономишь место и ускоряешь fsck. ## Block size Default 4 KiB на x86. Поддерживается 1/2/4 KiB. Не меняй без причины: - 4K - оптимум под page size ядра - <4K - тратится больше overhead - >4K - не поддерживается на x86 (на ARM/POWER можно 16K, 64K) ## noatime, relatime, lazytime По POSIX каждое чтение должно обновлять `atime` ([inode](/kb/inode.md)). Это **запись на каждое чтение** - убийственно для производительности. | Опция | Что | |-------|-----| | `atime` (default) | атовик при каждом чтении | | `relatime` | atime обновляется если предыдущий < mtime/ctime, или старше суток | | `noatime` | вообще не трогать atime | | `lazytime` | timestamp'ы только в кеше, на диск раз в сутки | Для прода - `noatime` или `lazytime`. Современные дистро ставят `relatime` по дефолту. ```fstab UUID=... / ext4 defaults,noatime,lazytime,errors=remount-ro 0 1 ``` ## Полезные mkfs/tune2fs опции ```bash # Создание mkfs.ext4 -L data -m 1 -E lazy_itable_init=1,lazy_journal_init=1 /dev/sdb1 ``` - `-L LABEL` - метка - `-m N` - резерв для root (default 5% - на 10TB это 500GB!) - `-E lazy_itable_init=1` - не зануляет inode table при создании (намного быстрее на больших дисках; фоновый процесс зануляет потом) - `-O ^has_journal` - **без** журнала (только если знаешь зачем, например: внешний `journal_dev` уже задан, или раздел временный) - `-T usage_type` - `news`, `largefile`, `largefile4` Тюнинг существующей: ```bash tune2fs -l /dev/sda1 # параметры ФС tune2fs -m 1 /dev/sda1 # уменьшить reserved до 1% tune2fs -L data /dev/sda1 # сменить label tune2fs -O ^has_journal /dev/sda1 # отключить журнал (опасно) tune2fs -c 0 -i 0 /dev/sda1 # отключить mount-count и time-based fsck ``` ## Online resize и shrink ext4 поддерживает **grow и shrink** на размонтированной ФС: ```bash # Grow (online или offline) resize2fs /dev/sda1 # до полного размера раздела resize2fs /dev/sda1 100G # до 100 GiB # Shrink (только offline) umount /dev/sda1 e2fsck -f /dev/sda1 # обязательная проверка resize2fs /dev/sda1 50G ``` В отличие от [xfs](/kb/xfs.md) (только grow) - это плюс ext4. ## fsck Только на размонтированной ФС: ```bash umount /mnt/data e2fsck -f /dev/sda1 # -f форсирует даже на "clean" e2fsck -y /dev/sda1 # -y "yes на все вопросы" (для скриптов) ``` Для root-партиции есть `errors=remount-ro` в fstab - при ошибке ФС автоматически перемонтируется в RO. Подробнее в [fsck-and-recovery](/kb/fsck-and-recovery.md). ## Когда что-то пошло не так - **`No space left` при свободном GB** - закончились inode (`df -i`). Удалить мелкие файлы или пересоздать ФС с `-i 4096`. - **`Read-only file system`** - `errors=remount-ro` сработал. Смотри `dmesg | grep EXT4-fs` для причины. Часто - bad sector. - **Файлы пропали после краша** - `data=writeback` без [[mount-and-fstab|fsync]] из приложения. Уроки: fsync(), `O_DSYNC` для критичных данных. - **Очень медленно после `mkfs` на большом диске** - `lazy_itable_init=1` ещё работает в фоне. `dmesg | grep ext4` покажет. - **`tune2fs: Filesystem has unsupported feature(s)`** - старый дистро не знает фичу. Посмотри `dumpe2fs -h /dev/sdX | grep features`, обнови `e2fsprogs`. - **5% reserved bytes** - на больших дисках `-m 1` или `-m 0`. Reserved нужен только для root-FS чтобы при заполнении система могла продолжать работать. ## Проверка состояния ```bash dumpe2fs -h /dev/sda1 # супер-блок без деталей групп debugfs -R 'stat ' /dev/sda1 # детали конкретного inode filefrag -v /path/to/file # фрагментация конкретного файла e4defrag /path # online defrag (редко нужен) ``` ## Команды ```bash sudo mkfs.ext4 -L data -m 1 -E lazy_itable_init=1 /dev/sdb1 ``` Создать ext4 с label, reserved=1%, без блокировки на zero-init таблицы ```bash sudo tune2fs -l /dev/sda1 ``` Все параметры ФС: размер блока, mount count, last fsck, features ```bash df -i / ``` Использование inode (не GB) - часто упирается раньше места ```bash sudo resize2fs /dev/sda1 ``` Расширить ФС до полного размера раздела (после parted resize) ```bash sudo mount -o remount,noatime,lazytime / ``` Применить noatime+lazytime без перезагрузки - проверка перед fstab ```bash sudo e2fsck -f /dev/sdb1 ``` Force-проверка размонтированной ФС - перед ресайзом обязательно ```bash sudo dumpe2fs -h /dev/sda1 | grep -i feature ``` Список включённых features - проверить совместимость со старыми ядрами ## См. также - [Файловые системы: ext4, xfs, btrfs, zfs](/kb/filesystems.md) - [Inode](/kb/inode.md) - [mount и /etc/fstab - подключение ФС](/kb/mount-and-fstab.md) - [fsck и recovery - проверка и восстановление ФС](/kb/fsck-and-recovery.md) - [LVM - Logical Volume Manager](/kb/lvm.md) - [Kubernetes storage - PV, PVC, StorageClass, CSI](/kb/kubernetes-storage.md)