Что означает ошибка No space left on device
Ошибка No space left on device (код ENOSPC) — это системное сообщение от ядра Linux, которое означает, что операция записи на диск не может быть выполнена из-за полного заполнения целевой файловой системы. Она возникает в консоли или в логах приложений (например, веб-сервера, базы данных, системы сборки) при попытке создать, изменить или переместить файл.
Типичные симптомы:
- При запуске команды
touch newfileили установке пакета черезapt/yumпоявляется сообщениеNo space left on device. - Сбои в работе служб, которые пишут логи или данные (например, MySQL, PostgreSQL, Docker).
- Веб-сервер (Nginx/Apache) возвращает ошибку 500 и пишет в лог
disk full. - Системные уведомления о нехватке места (в GUI-окружениях).
Причины возникновения
Ошибка возникает по одной основной причине — физическое или логическое заполнение раздела диска до 100%. Конкретные сценарии:
- Корневой раздел (
/) заполнен. Частая проблема на виртуальных серверах или при неаккуратном управлении пакетами и логами. - Раздел
/varили/var/logразрастается из-за неограниченного хранения логов, кэша пакетов или данных приложений (например, базы данных). - Множество «висячих» файлов. Файлы, которые были удалены (
rm), но всё ещё открыты каким-либо процессом. Они продолжают занимать место до завершения процесса. - Огромные файлы дампов или бэкапов, оставленные в домашних каталогах (
/home) или в/tmp. - Раздел подкачки (swap) заполнен (редко, но возможно при системной нестабильности).
- Резервирование места для root. По умолчанию в ext4/xfs 5% места резервируется для root-пользователя. На больших дисках это может быть гигабайтами, недоступными обычному пользователю.
Способы решения
Способ 1: Диагностика и поиск больших файлов (базовый)
Первым делом нужно понять, что именно занимает место.
- Проверьте все смонтированные файловые системы:
df -h
Ключ-hделает вывод «человекочитаемым» (в МБ, ГБ). Найдите раздел сUse%равным100%или близким к этому. Обычно это/,/homeили/var. - Узнайте, какие каталоги в этом разделе самые большие. Например, если заполнен корень (
/):sudo du -sh /* 2>/dev/null | sort -rh | head -n 20sudo— нужен для доступа ко всем каталогам.du -sh— вычисляет суммарный размер каталога (-s) в удобном формате (-h)./*— сканируем сразу все каталоги в корне.2>/dev/null— подавляем ошибки «Permission denied».sort -rh— сортируем по убыванию размера (reverse, human numeric).head -n 20— показываем топ-20.
Результат: вы увидите список вроде:45G /var 12G /home 8.5G /usr ...
Теперь углубитесь в самый большой каталог (например,/var):sudo du -sh /var/* 2>/dev/null | sort -rh | head -n 10 - Поиск конкретных больших файлов (если нужно найти файлы, а не каталоги):
sudo find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | awk '{ print $5, $9 }' | sort -rh | head -n 20
Эта команда найдет все файлы размером более 100 МБ и выведет их размер и путь, отсортированные по убыванию.
Способ 2: Удаление «висячих» файлов (deleted but still open)
Иногда место занято файлами, которые были логически удалены командой rm, но остаются открытыми работающим процессом. Такие файлы не отображаются в du, но df показывает, что место занято.
- Найдите такие файлы:
sudo lsof | grep '(deleted)'
Или для конкретного раздела:sudo lsof / | grep '(deleted)' - В выводе вы увидите что-то вроде:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mysqld 1234 mysql 8w REG 253,0 10G 1234567 /var/lib/mysql/ibdata1 (deleted)
Здесь файл/var/lib/mysql/ibdata1размером 10 ГБ удалён, но всё ещё используется процессомmysqld(PID 1234). - Освободите место. Есть два пути:
- Перезапустите процесс (если это возможно без потери данных):
sudo systemctl restart mysql. - Усеките файл (более агрессивно, но иногда необходимо):
sudo cat /dev/null > /proc/1234/fd/8. Это обнулит файловый дескриптор. Внимание: это может привести к corruption данных в приложении! Используйте только если уверены, что процесс может пересоздать файл (например, лог-файл).
- Перезапустите процесс (если это возможно без потери данных):
Способ 3: Очистка кэша пакетного менеджера и старых ядер
Системные пакетные менеджеры и обновления ядра — частые виновники заполнения /var.
- Для Debian/Ubuntu:
# Очистка кэша скачанных .deb пакетов sudo apt-get clean # Удаление старых, ненужных пакетов и ядер sudo apt-get autoremove --purge # Дополнительно: удаление старых версий пакетов из кэша (если clean не сработал) sudo apt-get autoclean - Для RHEL/CentOS/Fedora:
# Очистка всего кэша yum/dnf sudo yum clean all # для CentOS 7 sudo dnf clean all # для CentOS 8+/Fedora # Удаление старых ядер (осторожно! оставьте как минимум 2: текущий и предыдущий) sudo package-cleanup --oldkernels --count=2
Способ 4: Очистка системных логов и временных файлов
- Очистка текущих логов (если
logrotateне настроен или сломан):# Очистка основного системного лога (обычно самый большой) sudo sh -c 'cat /dev/null > /var/log/syslog' # Для journald (systemd-логи) лучше использовать встроенную утилиту sudo journalctl --vacuum-time=3d # оставить логи только за последние 3 дня sudo journalctl --vacuum-size=100M # оставить не более 100 МБ - Очистка временных файлов:
# Очистка /tmp (убедитесь, что там нет важных файлов!) sudo rm -rf /tmp/* sudo rm -rf /var/tmp/* # Очистка кэша браузеров (если это рабочая станция) rm -rf ~/.cache/mozilla/firefox/*.default/cache2/* rm -rf ~/.cache/google-chrome/Default/Cache/*
Способ 5: Работа с Docker (если используется)
Docker — известный «пожиратель» места из-за образов, контейнеров и volumes.
- Удалите неиспользуемые образы, контейнеры, сети и тома:
# Удалить ВСЁ, что не используется (осторожно!) docker system prune -a --volumes # Более безопасно: сначала посмотреть, что будет удалено docker system prune -a --volumes --dry-run - Очистите конкретные ресурсы:
docker image prune -a # все неиспользуемые образы docker container prune # остановленные контейнеры docker volume prune # неиспользуемые тома docker network prune # неиспользуемые сети - Измените драйвер хранения Docker (если постоянно заполняется). По умолчанию —
overlay2. Для систем с ограниченным местом можно настроитьdevicemapperили смонтировать/var/lib/dockerна отдельный диск.
Профилактика
- Настройте
logrotate. Убедитесь, что конфиги в/etc/logrotate.confи/etc/logrotate.d/активны и корректно ограничивают размер/возраст логов (например,size 100M,rotate 7). - Настройте мониторинг. Добавьте в
cronзадачу, которая шлёт уведомление при заполнении раздела более чем на 85%:# /etc/cron.daily/disk-space-check #!/bin/bash THRESHOLD=85 CURRENT=$(df / | awk 'NR==2 {print $5}' | tr -d '%') if [ "$CURRENT" -ge "$THRESHOLD" ]; then echo "Критично: раздел / заполнен на $CURRENT%" | mail -s "Диск переполнен на $(hostname)" admin@example.com fi - Регулярно выполняйте
apt-get clean/yum clean allпосле массовых обновлений. - Используйте отдельные разделы или диски для
/var,/home,/var/logна серверах. Это изолирует проблему. - Устанавливайте
ncdu— интерактивный инструмент для анализа дискового пространства (sudo ncdu /). Он удобнееduдля интерактивного изучения.