PQ
PQ.Hosting

Валюта

Что нужно знать о inode в Linux: диагностика, исчерпание и практические команды

Автор
PQ
03 марта 2026
5 мин чтения
896 просмотров
Что нужно знать о inode в Linux: диагностика, исчерпание и практические команды

Системный администратор получает тикет: «Диск заполнен, но df -h показывает 40% свободного места». Классическая ловушка для тех, кто не знает об inode. Сервер отказывается создавать новые файлы не из-за нехватки места — из-за нехватки индексных узлов. Именно здесь начинается настоящее знакомство с тем, как Linux хранит данные на самом деле.

Два слоя хранения данных

Большинство пользователей думают, что файл — это просто имя и содержимое. На самом деле каждый файл существует в двух независимых местах.

Первое — блоки данных: физические секторы диска, где лежит содержимое. Второе — inode (Index Node): отдельная структура фиксированного размера, где хранятся все метаданные об этом содержимом. А имя файла — это третья, совершенно отдельная вещь. Оно хранится в записи директории и просто указывает на номер inode.

Удалите запись в директории — inode никуда не денется, пока на него есть хотя бы одна ссылка. Это фундамент того, как работают жёсткие ссылки и почему открытый процессом файл можно восстановить даже после rm.

Система косвенных указателей — не просто архитектурная деталь. Именно благодаря ей ext4 адресует файлы размером до 16 ТБ, сохраняя inode фиксированного размера в 256 байт.

Что конкретно хранит inode

В отличие от распространённого заблуждения — имени файла в inode нет. Есть всё остальное:

размер файла в байтах, идентификатор устройства хранения, UID и GID владельца, маска прав доступа (mode), флаги файла, три временны́е метки (atime, mtime, ctime), счётчик жёстких ссылок и указатели на блоки данных. Блоки адресуются иерархически: прямые указатели для маленьких файлов, косвенные для средних, двойные косвенные для больших.

Три временны́е метки: в чём разница

Путаница между atime, mtime и ctime — источник неочевидных ошибок в скриптах резервного копирования и мониторинга.

mtime меняется при изменении содержимого файла. ctime — при изменении содержимого или метаданных inode (смена прав, владельца, жёстких ссылок). atime — при каждом чтении файла. Именно из-за atime на нагруженных серверах с тысячами обращений к одним и тем же файлам возникают лишние операции записи. Решение — опция монтирования noatime в /etc/fstab:

/dev/sda1 / ext4 defaults,noatime 0 1

На VPS с SSD-хранилищем это снижает износ диска и количество I/O-операций без потери функциональности.

Узнать номер inode и метаданные файла

Быстрый способ — флаг -i команды ls:

ls -i /etc/nginx/nginx.conf

Вывод будет примерно таким:

786435 /etc/nginx/nginx.conf

Для развёрнутой картины — команда stat:

stat /etc/nginx/nginx.conf
  File: /etc/nginx/nginx.conf
  Size: 2893       Blocks: 8      IO Block: 4096  regular file
Device: 802h/2050d  Inode: 786435   Links: 1
Access: 2026-02-28 10:15:00
Modify: 2026-02-01 14:22:10
Change: 2026-02-01 14:22:10

stat показывает все три метки сразу — удобно для отладки скриптов, которые ориентируются на время изменения.

Inode заканчиваются: диагностика и поиск причины

Каждый раздел создаётся с фиксированным лимитом inode. Этот лимит задаётся при форматировании и потом не меняется (для ext4 без специальных манипуляций). На VPS и выделенных серверах исчерпание inode — не экзотика. Пара сотен тысяч временных файлов PHP-сессий или очередь Postfix из миллиона писем — и система перестаёт принимать новые файлы.

Посмотреть заполненность inode по всем разделам:

df -i
Filesystem      Inodes   IUsed   IFree IUse% Mounted on
/dev/vda1      1310720  128000 1182720   10% /
/dev/vda2       655360  655360       0  100% /var/spool
tmpfs           512000       1  511999    1% /run

Раздел /var/spool на 100% — почтовый сервер встал. Свободного места на диске может быть хоть 50 ГБ.

Найти виновника — директорию с аномально большим числом файлов:

find /var -xdev -printf '%h\n' | sort | uniq -c | sort -rn | head -15

Команда выводит директории отсортированные по количеству файлов в них. Типичная картина: /var/spool/postfix/deferred с сотнями тысяч вложенных файлов, /tmp/sessions от PHP, /var/cache от пакетных менеджеров.

Найти файл по номеру inode

Сценарий встречается реже, чем хотелось бы думать: файл есть на диске, но имя неизвестно или содержит символы, которые нельзя набрать с клавиатуры. Например, файл создан через ошибку в скрипте и имя начинается с дефиса или содержит пробелы с управляющими символами.

find /home -inum 786435

Ключ -inum принимает номер inode. Ограничение поиска конкретным разделом (/home вместо /) ускоряет работу в несколько раз.

Удалить такой файл безопаснее тоже через inode:

find /home -inum 786435 -delete

Жёсткие ссылки и счётчик ссылок

Жёсткая ссылка — не копия файла и не «ссылка» в привычном смысле. Это второе имя, указывающее на тот же inode. Данные на диске единственные, счётчик ссылок увеличивается:

ln /var/log/app.log /backup/app_hardlink.log
stat /var/log/app.log | grep Links
# Links: 2

Файл исчезнет с диска только когда счётчик опустится до нуля. Поэтому rm технически называется unlink — он не удаляет данные, а отсоединяет имя от inode. Если на inode больше нет ссылок и ни один процесс не держит файл открытым — ядро освобождает блоки.

Отсюда практическое следствие: если удалить файл лога пока в него пишет nginx, файл «исчезнет» из директории, но место на диске не освободится до перезапуска nginx (или отправки сигнала USR1).

Восстановить удалённый файл через /proc

Пока процесс держит файл открытым — данные живы в /proc/PID/fd/:

# Найти дескриптор удалённого файла
lsof | grep deleted | grep nginx

# Скопировать через proc
cp /proc/12345/fd/7 /var/log/app_recovered.log

Это работает только пока процесс не завершился. После — только fsck или специализированные инструменты восстановления типа extundelete.

Шпаргалка

Задача Команда
Номер inode файла ls -i filename
Все метаданные inode stat filename
Использование inode по разделам df -i
Найти файл по номеру inode find /path -inum НОМЕР
Удалить файл по inode find /path -inum НОМЕР -delete
Директории с наибольшим числом файлов find /path -xdev -printf '%h\n' | sort | uniq -c | sort -rn | head
Создать жёсткую ссылку ln source linkname
Счётчик жёстких ссылок stat filename | grep Links
Восстановить удалённый открытый файл cp /proc/PID/fd/FD /path/recovered

Поделиться статьей

Похожие статьи