Что означает ошибка "No space left on device" (ENOSPC)
Ошибка No space left on device (код ошибки ENOSPC) — это системное сообщение от ядра Linux, которое означает, что на целевом дисковом разделе закончилось свободное место для записи. Она может возникать в любом приложении, службе или при попытке выполнить команду в терминале, требующую записи на диск. Типичные проявления:
- В терминале:
bash: cannot create temp file for here-document: No space left on device - В логах приложений:
java.io.IOException: No space left on device - При установке пакета:
E: Sub-process /usr/bin/dpkg returned an error code (1) - В веб-сервере (nginx/apache): ошибка записи логов или загрузки файлов.
Ошибка критична — она полностью блокирует любые операции записи на проблемный раздел, что может привести к остановке служб, невозможности входа в систему (если заполнен /) или повреждению данных.
Причины возникновения
Ошибка имеет конкретные и часто предсказуемые причины:
- Накопление лог-файлов: Бесконтрольный рост файлов в
/var/log(особенноsyslog,messages,kern.log) из-за высокой нагрузки или не настроенногоlogrotate. - Кэши пакетных менеджеров: Огромные кэши
.debили.rpmпакетов в/var/cache/aptи/var/cache/yum. - Временные файлы и кэши приложений: Файлы в
/tmp,/var/tmp, кэши браузеров, IDE, кэшnpm,pip,cargoи т.д. - "Висячие" контейнеры и образы Docker: Неудалённые после остановки контейнеры, неиспользуемые образы и тома в
/var/lib/docker. - Ядерные модули и дампы: Файлы дампов памяти (
core dumps) или старые ядра (/bootили/lib/modules). - Исчерпание inode: На разделе закончилось количество доступных метаданных файлов (inodes), хотя место по объёму может быть. Это часто происходит при хранении миллионов мелких файлов.
- Резервные копии и логи приложений: Ручное размещение больших
.tar.gz,.bakфайлов в домашних каталогах или корне. - Скрытые файлы, удалённые но занятые процессами: Файл удалён (
rm), но процесс всё ещё держит на него дескриптор, освобождая место только после завершения процесса или его перезапуска.
Способы решения
Способ 1: Быстрая диагностика и очистка кэшей
Этот способ решает проблему в 80% случаев и является первым, что нужно сделать.
- Определите проблемный раздел:
df -h
Найдите раздел сUse%100% или близко к этому. Запомните точку монтирования (например,/,/var,/home). - Проверьте использование inode (важный шаг!):
df -i
ЕслиIUse%также 100%, проблема в количестве файлов, а не в объёме. Решение — удаление мелких файлов (часто в/var/logили кэшах). - Очистите кэш пакетного менеджера (выберите нужный):
- Для Debian/Ubuntu:
Это удалит все файлы пакетов изsudo apt-get clean/var/cache/apt/archives. Может освободить сотни мегабайт или гигабайты. - Для CentOS/RHEL/Fedora:
sudo yum clean all # или для dnf sudo dnf clean all
- Для Debian/Ubuntu:
- Очистите временные файлы:
sudo rm -rf /tmp/* sudo rm -rf /var/tmp/*
Внимание: Убедитесь, что нет важных данных в этих папках. Лучше сначала посмотреть содержимое. - Очистите кэш systemd-journald (если используется):
# Удалить старые журналы, оставив только последние 100МБ sudo journalctl --vacuum-size=100M # ИЛИ удалить журналы старше 7 дней sudo journalctl --vacuum-time=7d
Способ 2: Глубокий анализ и удаление больших файлов
Если первый способ не помог, нужно найти "пожирателей" диска.
- Перейдите в проблемный раздел (например,
/var):cd /var - Найдите 20 самых больших каталогов/файлов:
sudo du -sh * 2>/dev/null | sort -rh | head -20
Командаsudoнужна, чтобы избежать ошибок доступа.2>/dev/nullподавляет сообщения "Permission denied". Результат покажет список вроде:45G log 12G cache 8G lib/docker - Исследуйте подозрительные каталоги. Например, для
/var/log:sudo du -sh /var/log/* | sort -rh | head -10
Вы увидите конкретные файлы. Частые "виновники":/var/log/syslogили/var/log/messages(огромный, неархивированный лог)/var/log/apache2/или/var/log/nginx/(логи доступа/ошибок)/var/lib/docker/containers/(логи контейнеров)
- Очистите или архивируйте логи:
- Архивация старых логов:
sudo gzip -9 /var/log/syslog.1(уменьшит размер). - Усечение активного лога (осторожно!):
sudo truncate -s 0 /var/log/syslog # После этого перезапустите службу, которая пишет в этот файл sudo systemctl restart rsyslog - Удаление старых сжатых логов:
sudo rm -f /var/log/*.gzилиsudo rm -f /var/log/*.[0-9].
- Архивация старых логов:
Способ 3: Работа с Docker (если установлен)
Docker — один из главных "пожирателей" места в /var.
- Удалите остановленные контейнеры:
docker ps -a | grep Exited | awk '{print $1}' | xargs docker rm - Удалите неиспользуемые образы (включая промежуточные):
docker image prune -a
Это удалит все образы, на которые нет ссылок от контейнеров. Внимание: если вы собираете образы локально, они могут быть удалены. - Удалите висячие тома:
docker volume prune - Или полная очистка всего (крайняя мера, удалит ВСЁ):
docker system prune -a --volumes
Способ 4: Очистка кэша пользователей и приложений
Кэши приложений в домашних каталогах могут занимать гигабайты.
- Очистите кэш браузеров (Firefox, Chrome):
- Firefox:
rm -rf ~/.cache/mozilla/firefox/*.default/cache2/ - Chrome/Chromium:
rm -rf ~/.cache/google-chrome/Default/Cache/
- Firefox:
- Очистите кэш Flatpak/Snap (если используете):
# Flatpak flatpak uninstall --unused # Snap sudo snap set system refresh.retain=2 # Оставить только 2 последних ревизий - Очистите кэши языковых пакетов:
# Python (pip) pip cache purge # Node.js (npm) npm cache clean --force # Rust (cargo) cargo clean
Способ 5: Работа с inodes и "невидимыми" файлами
Если df -i показывает 100% использования, но df -h — нет.
- Найдите каталог с наибольшим числом файлов:
for i in /*; do echo $i; find $i -type f | wc -l; done | sort -rn | head -20
Это может занять время. Ищите каталог с аномально большим числом (миллионы). - Удалите мелкие файлы в найденном каталоге (часто это
/var/spool,/var/tmp, кэши). - Проверьте "висячие" дескрипторы удалённых файлов:
sudo lsof | grep deleted
Если есть строки вида:java 12345 user REG 8,1 1024M 12345678 /tmp/hsperfdata_user (deleted)
Это значит, что процессjava(PID 12345) всё ещё держит дескриптор на удалённый большой файл. Перезапустите этот процесс (sudo systemctl restart <service>), и место освободится.
Профилактика
Чтобы проблема не возникала снова:
- Настройте
logrotateдля всех логов. Убедитесь, что в/etc/logrotate.confи файлах в/etc/logrotate.d/есть параметры:/var/log/syslog { rotate 7 daily compress delaycompress missingok notifempty create 640 syslog adm sharedscripts postrotate /usr/lib/rsyslog/rsyslog-rotate endscript } - Установите мониторинг дискового пространства. Простой скрипт для
cron(каждый час):# /usr/local/bin/disk-monitor.sh THRESHOLD=90 df -h | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $6 }' | while read OUTPUT; do USAGE=$(echo $OUTPUT | awk '{ print $1}' | cut -d'%' -f1) PARTITION=$(echo $OUTPUT | awk '{ print $2 }') if [ $USAGE -ge $THRESHOLD ]; then echo "Внимание: раздел $PARTITION заполнен на $USAGE%" | mail -s "Disk Alert on $(hostname)" admin@example.com fi done
Добавьте в crontab:0 * * * * /usr/local/bin/disk-monitor.sh. - Регулярно чистите кэши. Добавьте в
cronежемесячную очистку кэшаapt/yumи старых логов. - Используйте квоты диска (
quota) для пользователей, если несколько пользователей работают на одном сервере. - Оцените необходимость ротации логов Docker. Настройте
log-opt max-sizeиmax-fileв/etc/docker/daemon.json:{ "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }
Перезапустите Docker:sudo systemctl restart docker.