«Диск забит на 100%» — одна из самых частых причин отказа сервисов: перестают работать базы, логи и почта. Разберём, как быстро найти, что именно съело место, чем df отличается от du и как почистить диск без потери данных.

df: общая картина

df показывает состояние смонтированных файловых систем: общий объём, занято, свободно и процент заполнения. Начинать всегда стоит с него.

# человекочитаемый вывод
df -h
# без виртуальных файловых систем
df -h -x tmpfs -x devtmpfs
# точка монтирования, которую проверяем
df -h /var
# inode: бывает, что места много, а inode кончились
df -i

Второй случай неочевиден: масса мелких файлов исчерпывает inode раньше места. Признак — df -h показывает запас, а запись невозможна.

du: что именно занимает место

du считает занятое место в каталогах. Запускайте по корневым директориям и идите вглубь, а не сканируйте весь диск сразу.

# топ каталогов верхнего уровня
sudo du -xh --max-depth=1 / 2>/dev/null | sort -h | tail -15
# углубляемся
sudo du -xh --max-depth=1 /var 2>/dev/null | sort -h | tail -10
sudo du -xh --max-depth=1 /var/log 2>/dev/null | sort -h | tail -10
# самые большие файлы
sudo find / -xdev -type f -size +500M -exec ls -lh {} \; 2>/dev/null | head -20

Флаг -x не даёт уйти на другие разделы: иначе отчёт смешает несколько файловых систем.

Типичные виновники

  • Логи без ротации: /var/log растёт годами.
  • Неочищенный кэш пакетов: /var/cache/apt.
  • Огромные снапшоты или дампы баз данных.
  • Контейнеры и образы: /var/lib/docker.
  • Повисшие файлы удалённых процессов: они держат место, пока не закрыт дескриптор.
  • Временные файлы в /tmp и /var/tmp.
# диагностика по каждому подозреваемому
sudo du -sh /var/log /var/cache/apt /var/lib/docker /var/lib/containers 2>/dev/null
# освобождённые, но занятые файлы
sudo lsof +L1 2>/dev/null | head -20
# размер дампов
ls -lh /var/backups/*.sql* 2>/dev/null | head

Безопасная очистка

Чистите по одному каталогу и проверяйте результат. Никогда не удаляйте файлы, не понимая, кому они принадлежат.

# кэш пакетов
sudo apt clean
# старые логи (оставить 7 дней)
sudo journalctl --vacuum-time=7d
sudo find /var/log -name "*.gz" -mtime +30 -delete
# кэш контейнеров
docker system df 2>/dev/null
docker system prune -f 2>/dev/null
# после очистки
df -h /

Команды с rm -rf набирайте только после проверки пути через ls. Опечатка в подобной команде стоит данных.

Удалённые файлы, которые держат диск

Если процесс пишет в уже удалённый файл, место не освобождается до перезапуска программы. Находится это по выводу lsof.

# найти удалённые файлы с открытыми дескрипторами
sudo lsof +L1 | awk '$7 < 0 {print $1, $2, $9}' | head -20
# перезапустить конкретную службу
sudo systemctl restart nginx
# проверить
df -h /var

Профилактика

Настройте ротацию логов, квоты и мониторинг заполнения. Проще получить оповещение на 80%, чем лечить отказ на 100%.

# ротация через logrotate
cat /etc/logrotate.d/nginx 2>/dev/null
# проверить применение конфига
sudo logrotate -d /etc/logrotate.conf | tail -20
# мониторинг места: простой cron
# */30 * * * * df -h / | grep -qE '9[0-9]%' && echo "диск почти полон" | mail -s alert admin@example.com

Для баз данных планируйте ротацию дампов и храните несколько последних версий, а не все подряд.

Когда места мало, а файлов не видно

Причины: занятые inode, неправа на чтение (при сканировании без root часть каталогов пропускается), смонтированный в подкаталог раздел.

# inode
df -i
# права: запускайте du от root
sudo du -xh --max-depth=1 /var 2>/dev/null | sort -h | tail
# точки монтирования
findmnt -D | head -20
cat /proc/mounts | grep -vE "proc|sys|cgroup" | head

Когда раздел нужно расширить

Очистка не всегда помогает: данные растут, и правильное решение — увеличить раздел. На LVM это делается онлайн, на обычном разделе — переносом данных.

# состояние LVM
sudo pvs && sudo vgs && sudo lvs
# рост логического тома и файловой системы
sudo lvextend -L +5G /dev/mapper/vg0-root
sudo resize2fs /dev/mapper/vg0-root   # ext4
# для XFS
# sudo xfs_growfs /
df -h /

Если свободного места в группе томов нет, добавьте физический том: pvcreate /dev/sdb1, затем vgextend и повторите рост.

Квоты на мелкие файлы

Хостинг с тысячами пользователей упирается не в место, а в inode и рост каталогов. Квоты ограничивают каждого отдельно и убирают необходимость разбирать общий диск.

# включить квоты на разделе (fstab: usrquota,grpquota)
sudo quotacheck -cum /
sudo quotaon /
# лимит для пользователя
sudo setquota -u deploy 5G 6G 200000 210000 /
# проверить
sudo repquota -us | head -15

Периодически смотрите отчёт по квотам: он сразу показывает, кто из пользователей приближается к лимиту.

Автоматические отчёты о заполнении

Вместо ручной проверки раз в месяц настройте короткий отчёт по ключевым разделам. Он приходит по почте или в мессенджер и показывает динамику: диск заполняется постепенно, и по тренду видно, когда он закончится.

#!/bin/bash
# /usr/local/bin/disk-report.sh
for m in / /var /home; do
  pct=$(df -h "$m" | awk 'NR==2 {print $5}')
  echo "$m -> $pct"
done | grep -E '[89][0-9]%|100%' || true

# cron: отчёт раз в день
# 0 9 * * * /usr/local/bin/disk-report.sh | head -5

Дополните отчёт местом под снапшоты и дампами: они часто растут быстрее остальных данных и незаметно заполняют раздел.

Итог

Порядок простой: df -h — где переполнено, df -i — не кончились ли inode, du вглубь — кто виноват, затем точечная очистка. Настройте ротацию логов и оповещения о заполнении: так вы узнаете о проблеме до отказа сервисов.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте