Зачем именно 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 или btrfs.
Журналирование
Главное отличие от ext2 - journal (журнал). Когда меняется метаданные (inode/директории/bitmap), сначала пишется план изменений в кольцевой журнал, потом сами изменения. Краш до commit'а журнала - откатываемся, после - дочитываем журнал и применяем.
Три режима, выбираются mount -o data=...:
| Режим | Что журналируется | Когда |
|---|---|---|
data=writeback | только метаданные; данные могут попасть на диск ДО или ПОСЛЕ метаданных | максимальная скорость, риск "файл указывает на чужие блоки" после краша |
data=ordered (default) | метаданные после fsync данных | компромисс: метаданные согласованы с данными |
data=journal | и метаданные, и данные через журнал | максимальная безопасность, медленнее в 2x |
Для БД иногда выгодно data=writeback + WAL приложения берёт на
себя crash-safety. Для контейнерного хоста - default.
Журнал лежит на той же ФС в специальном inode (8). Можно вынести на отдельный быстрый диск:
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, кэш) - повышай плотность:
# 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). Это
запись на каждое чтение - убийственно для производительности.
| Опция | Что |
|---|---|
atime (default) | атовик при каждом чтении |
relatime | atime обновляется если предыдущий < mtime/ctime, или старше суток |
noatime | вообще не трогать atime |
lazytime | timestamp'ы только в кеше, на диск раз в сутки |
Для прода - noatime или lazytime. Современные дистро ставят
relatime по дефолту.
UUID=... / ext4 defaults,noatime,lazytime,errors=remount-ro 0 1
Полезные mkfs/tune2fs опции
# Создание
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
Тюнинг существующей:
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 на размонтированной ФС:
# 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 (только grow) - это плюс ext4.
fsck
Только на размонтированной ФС:
umount /mnt/data
e2fsck -f /dev/sda1 # -f форсирует даже на "clean"
e2fsck -y /dev/sda1 # -y "yes на все вопросы" (для скриптов)
Для root-партиции есть errors=remount-ro в fstab - при ошибке ФС
автоматически перемонтируется в RO. Подробнее в fsck-and-recovery.
Когда что-то пошло не так
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 чтобы при заполнении система могла продолжать работать.
Проверка состояния
dumpe2fs -h /dev/sda1 # супер-блок без деталей групп
debugfs -R 'stat <inode>' /dev/sda1 # детали конкретного inode
filefrag -v /path/to/file # фрагментация конкретного файла
e4defrag /path # online defrag (редко нужен)