Диск: df, du, mount, разделы
Куда уходит место и почему «диск полный»: df vs du, точки монтирования, inode и удалённые открытые файлы.
«На диске нет места»
Самая частая авария на сервере: кончилось место, и сервис встал. Чтобы её
разобрать, нужны две команды: df (сколько занято на разделах) и du
(кто именно занимает).
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 38G 0.5G 99% /
/dev/vdb1 100G 12G 83G 13% /var/lib/postgresql
tmpfs 2.0G 0 2.0G 0% /run
df -h показывает разделы и их заполнение в человекочитаемом виде.
Колонка Use% сразу говорит, где беда: корень / занят на 99%.
df против du
Это разные инструменты, их путают.
dfсмотрит на файловые системы: сколько всего, занято и свободно на каждом разделе. Отвечает «какой раздел переполнен».duсчитает размер каталогов: сколько занимают файлы внутри. Отвечает «что именно съело место».
Связка такая: df показал, что переполнен /, дальше du ищет виновника:
$ du -sh /var/* | sort -h | tail -5
1.2G /var/cache
3.4G /var/lib
12G /var/log
du -sh /var/* даёт размер каждого подкаталога, sort -h сортирует
по-человечески (с учётом G/M/K), tail -5 показывает топ. Виновник —
/var/log на 12 гигабайт.
Точки монтирования
Раздел становится доступен, когда его примонтировали в какую-то точку
дерева. В выводе df колонка Mounted on — это и есть точки монтирования.
/var/lib/postgresql на отдельном диске /dev/vdb1: данные базы живут не
на корневом разделе.
Это важно при разборе: место может кончиться на /, пока на
/var/lib/postgresql его полно. Они физически разные диски. df -h <путь>
покажет, на каком разделе лежит конкретный путь.
Дерево дисков и их разделов с точками монтирования показывает lsblk:
$ lsblk
NAME SIZE TYPE MOUNTPOINT
vda 40G disk
└─vda1 40G part /
vdb 100G disk
└─vdb1 100G part /var/lib/postgresql
Видно физические диски (vda, vdb), их разделы (vda1) и куда каждый
примонтирован. Команда mount без аргументов выводит то же плюс опции
монтирования (ro, noexec и прочие).
Когда df и du расходятся
Бывает: df говорит «занято», а du той же папки показывает мало.
Частая причина — удалённый, но открытый файл. Процесс держит файл
открытым, кто-то его удалил (rm), но место не освободилось: ядро держит
его, пока процесс не закроет дескриптор или не перезапустится.
Найти такие файлы:
sudo lsof +L1
+L1 отбирает файлы, у которых число ссылок меньше единицы, то есть ровно
удалённые, но ещё открытые. Root тут нужен: без него lsof не заглянет в
чужие процессы и завалит вывод строками Permission denied.
В минимальных образах и контейнерах lsof часто не установлен. Тогда те же
дескрипторы видно прямо в procfs:
sudo ls -l /proc/*/fd 2>/dev/null | grep deleted
В выводе будет символическая ссылка вида /var/log/app.log (deleted), а
номер процесса берётся из строки заголовка /proc/<pid>/fd: выше.
После рестарта виновного процесса место вернётся. Вторая причина
расхождения: du не видит файлы под точкой монтирования, которая
наложилась поверх.
Что важно запомнить
df показывает заполнение разделов («где переполнено»), du — размер
каталогов («что съело»). Разбор идёт df → du.
Разделы монтируются в точки дерева; место может кончиться на одном разделе,
пока на соседнем его полно. df -h <путь> скажет, какой это раздел.
Если df и du расходятся, ищи удалённые открытые файлы (sudo lsof +L1,
без lsof — sudo ls -l /proc/*/fd | grep deleted); место вернётся после
рестарта процесса.
В связке с бэкапами: переполненный диск часто означает, что забыли чистить старые логи или дампы.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс