Короткий ответ
Сначала df -h и df -i по всем точкам монтирования, затем du -xhd1 только по тому, который заполнен. Не делайте rm -rf /var/log и не чистите /home «на глаз». Частые безопасные источники: journald, apt archives, старые ядра, Docker overlay, удалённые, но открытые файлы (lsof +L1). Если df 100%, а du не сходится — место держит процесс; рестарт того процесса освободит блоки, rm уже ничего не даст.
Хост host.example (10.0.20.10), пользователь admin.
Симптомы и как отличить
- приложения пишут
No space left on device; apt-get updateобрывается на unpack;journalctlругается на systemd-journal;- SSH ещё жив, но
sudoне пишет/var/log/auth.log.
Отличия:
| Картина | Не гигабайты | Статья |
|---|---|---|
df -h свободно, df -i 100% | inode | Закончились inode |
Том в ro | диск/контроллер | Read-only ФС |
Только /var/log/journal | политика journald | Логи journald заняли диск |
| dpkg lock + ENOSPC | оборванный apt | dpkg заблокирован |
Возможные причины
- Рост
/var/log/journalбезSystemMaxUse. /var/cache/apt/archivesпосле неудачных upgrade.- Несколько
linux-imageв/boot(отдельный раздел 1 ГБ). - Docker/containerd: overlay2,
containerdsnapshots. - Дампы
coredumpctl,/var/crash, mysql binlog, backup в/tmp. - Файл 50 ГБ удалили, процесс держит fd —
duуже не видит,dfвидит.
Диагностика
df -hT
df -i
lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT
findmnt -t ext4,xfs,btrfsНа заполненном томе (пример — /):
sudo du -xhd1 / | sort -h
sudo du -xhd1 /var | sort -h
sudo du -xhd1 /var/log | sort -h
journalctl --disk-usage
sudo du -sh /var/cache/apt/archives /var/crash /var/tmp /tmpФлаг -x не уходит на другие ФС: иначе du / суммирует NFS и врёт.
Открытые удалённые:
sudo lsof +L1 | awk 'NR==1 || $3=="0"' | head
sudo lsof +L1 | awk '$3=="0" {s+=$7} END {print s}'Docker, если стоит:
sudo du -xhd1 /var/lib/docker 2>/dev/null | sort -h | tail
sudo docker system df/boot:
df -h /boot
dpkg -l 'linux-image-*' | grep ^iiРешение
Сценарий A. Journald
Точечно, с сохранением срока, который вам нужен для расследований:
sudo journalctl --vacuum-size=300MПостоянный лимит — в статье про journald, не отключайте journal.
Сценарий B. APT и ядра
sudo apt-get clean
sudo apt-get autoremove --purgeНа /boot удаляйте старые linux-image, оставив текущее и одно предыдущее:
uname -rСценарий C. Open-deleted
Найдите PID из lsof +L1. Рестарт этого сервиса (systemctl restart …), не reboot всего хоста, если можно избежать. После рестарта df должен упасть.
Сценарий D. Большие логи приложения
Ротация через logrotate для /var/log/nginx и т.п. Сжатие gzip старых файлов безопаснее удаления за сегодня.
Сценарий E. Нужно место прямо сейчас, виновник неизвестен
Ищите файлы >500 МБ:
sudo find / -xdev -type f -size +500M -printf '%s %p\n' 2>/dev/null | sort -n | tail -n 20Не удаляйте /var/lib/mysql, /var/lib/postgresql, /var/lib/docker/volumes. Сначала snapshot.
Что смотреть на Ubuntu 22.04 и 24.04 отдельно
На 22.04 journal по умолчанию persistent, если существует /var/log/journal; размер часто не ограничен явно, и на корне 100 ГБ journal спокойно занимает десятки гигабайт. На 24.04 то же плюс needrestart и более болтливый unattended-upgrades в term.log. Перед vacuum journal скопируйте journalctl -b -0 -o export на другой том: иначе инцидент ENOSPC останется без улик.
Типичная ловушка гипервизора: гость видит df 40 ГБ свободно, а datastore thin pool на хосте 0 байт. Тогда dd в файл на / получает I/O error, не ENOSPC. Проверьте dmesg на I/O error параллельно с df. Если thin pool — чините хранилище, не apt-get clean.
Для LVM thin в госте:
sudo lvs -o lv_name,data_percent,metadata_percent,lv_size
sudo vgs -o vg_name,vg_free,vg_sizedata_percent близко к 100 на thin LV даёт те же симптомы, что заполненный ext4. Расширение LV (lvextend -r) — только после свободного места в VG и snapshot политики.
Не удаляйте /var/lib/containerd и overlay Docker, пока docker ps -a не показал, что контейнеры расходные. На 24.04 docker system df -v показывает volumes по имени: volume с базой выглядит как «unused», если контейнер остановлен.
Отдельный раздел /boot на 1 ГБ после нескольких linux-image generic и HWE заполняется файлами initrd по 80–100 МБ. Команда dpkg -l 'linux-image-*' плюс uname -r обязательна до autoremove. Если /boot vfat EFI + отдельный ext4 /boot — df -h /boot /boot/efi оба.
Когда admin заходит по SSH и не может писать в home, а корень ещё не 100%, проверьте квоты:
sudo repquota -a
quota -u adminКвоты на Ubuntu Server по умолчанию выключены; если включены на /home, это не «диск кончился глобально».
Как проверить, что проблема устранена
df -h /
df -i /
journalctl --disk-usage
sudo systemctl is-system-running
sudo apt-get check
touch /tmp/.space-ok && rm /tmp/.space-okСервис, который падал с ENOSPC, должен писать лог. Повторите операцию, которая ломалась (пакет, backup, upload).
С admin@10.0.20.10 достаточно df -h в мониторинг: порог 80/90%, не 99%.
Если не помогло
dfвсё ещё 100%,duмаленький: сноваlsof +L1, snapshot LVM thin, qcow2 на гипервизоре.- Thin pool гипервизора заполнен — гость видит «диск полный» при пустом
du. Смотрите хост, не Ubuntu. - Btrfs:
btrfs filesystem usage— снимки subvolume. - Запись есть, чтение нет: не ENOSPC, а read-only.
Профилактика
- Отдельный LV под
/varи/var/logна нагруженных логами узлах. SystemMaxUseдля journald, logrotate приложений.- Алерт
df80%, отдельный алертdf -i. - Не складывать backup на системный диск
host.example.
FAQ
Почему du меньше df?
Другие ФС без -x, reserved blocks ext4 (обычно 5% root), open-deleted, snapshot.
Можно ли уменьшать reserved blocks?
tune2fs -m 1 на больших томах допустимо, на корне 100 ГБ экономия копеечная. Не ставьте 0% на системный диск.
rm большого файла не меняет df?
Процесс держит inode. lsof на путь или +L1.
Чистить /tmp через reboot?
На Ubuntu /tmp часто tmpfs или чистится systemd-tmpfiles. Reboot — грубый способ; лучше найти потребителя.
Безопасно ли удалять /var/log/journal целиком?
Хуже, чем vacuum: теряете историю инцидента. Используйте --vacuum-size / --vacuum-time.