«No space left on device» — одна из тех ошибок которая появляется в самый неподходящий момент. Сайт перестаёт принимать загрузки, база данных зависает, логи перестают писаться, деплой падает с непонятной ошибкой. Причина одна — диск заполнен до предела.
Паниковать не нужно. Ситуация решается за 10-30 минут даже на сильно загруженном сервере. Главное — действовать методично: сначала убеждаемся что проблема именно в месте, потом находим виновника, потом чистим. В этой статье разберём весь процесс от первого диагностического шага до настройки мониторинга чтобы такое не повторялось.
Убеждаемся что проблема в месте на диске
Перед тем как что-то делать — проверяем состояние диска.
Показывает занятое и свободное место на всех смонтированных разделах:
df -h
Флаг -h выводит размеры в человекочитаемом формате (GB, MB). Смотрите на колонку Use% — если там 100% или близко к тому, проблема найдена.
Типичный вывод когда диск полон:
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 50G 0 100% /
tmpfs 2.0G 0 2.0G 0% /dev/shm
Если Avail равен 0 и Use% равен 100% — подтверждено, работаем дальше.
Есть ещё одна ситуация которая симулирует заполненный диск при наличии свободного места — закончились иноды. Иноды это записи о файлах в файловой системе: можно иметь гигабайты свободного места, но если инодов нет — новые файлы создать невозможно.
Проверяет использование инодов:
df -i
Если в колонке IUse% видите 100% — проблема в инодах, а не в месте. Решение то же: найти и удалить лишние файлы, просто искать нужно не большие а многочисленные (тысячи мелких файлов в кешах, сессиях, временных директориях).
Находим что занимает место
Диск полон — нужно понять кто виновник. Сужаем поиск от корня файловой системы до конкретной директории.
Смотрим сколько занимает каждая директория верхнего уровня
Показывает размер каждой директории в корне, сортирует по убыванию:
du -sh /* 2>/dev/null | sort -rh | head -20
Флаги: -s суммирует содержимое директории вместо построчного вывода, -h — читаемый формат. 2>/dev/null скрывает ошибки доступа к системным директориям.
Смотрите на верхние строки — обычно виновник сразу виден. /var часто занимает больше всего на серверах из-за логов и баз данных.
Погружаемся глубже в подозрительную директорию
Показывает что внутри /var и сортирует по размеру:
du -sh /var/* 2>/dev/null | sort -rh | head -20
Повторяете для каждой подозрительной директории пока не доберётесь до конкретных файлов.
Находим самые большие файлы на всём диске
Ищет файлы крупнее 100 MB по всей файловой системе:
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | sort -k5 -rh | head -20
Это занимает немного больше времени чем du, но даёт список конкретных файлов с путями и размерами. Часто сразу видно: лог-файл на 20 GB, старый дамп базы, забытый архив.
Альтернатива — интерактивная утилита ncdu
Если установлена утилита ncdu — она удобнее для интерактивного исследования:
apt install ncdu -y # Debian/Ubuntu
dnf install ncdu -y # CentOS/AlmaLinux
Запускает интерактивный браузер дискового пространства:
ncdu /
Стрелками навигируете по директориям, сразу видите размеры, можно удалять файлы прямо из интерфейса клавишей d.
Чистим место — типичные виновники
Логи
Логи — самая частая причина заполненного диска на production серверах. Nginx, Apache, MySQL, приложения — все пишут логи. Если ротация не настроена или настроена плохо — за месяц легко накапливается 50-100 GB.
Смотрит размер системных логов:
du -sh /var/log/* | sort -rh | head -20
Проверяет размер конкретного лог-файла:
ls -lh /var/log/nginx/access.log
Для файлов которые активно пишутся нельзя просто удалить — сервис продолжит писать в удалённый файл и место не освободится. Правильный способ — очистить содержимое без удаления файла.
Очищает содержимое лог-файла не удаляя его:
> /var/log/nginx/access.log
Или:
truncate -s 0 /var/log/nginx/access.log
После очистки проверяете что сервис продолжает нормально работать и писать в файл.
Принудительно запускает ротацию всех логов через logrotate:
logrotate -f /etc/logrotate.conf
Удаляет старые сжатые логи (файлы .gz старше 30 дней):
find /var/log -name "*.gz" -mtime +30 -delete
Журнал systemd (journald)
Journald накапливает логи всех systemd-сервисов и может занять несколько гигабайт незаметно.
Показывает сколько места занимает журнал:
journalctl --disk-usage
Очищает журнал оставив только последние 500 MB:
journalctl --vacuum-size=500M
Очищает записи старше 2 недель:
journalctl --vacuum-time=2weeks
Кеши пакетных менеджеров
APT и DNF хранят скачанные пакеты которые после установки уже не нужны.
Очищает кеш APT (Debian/Ubuntu):
apt clean
Удаляет кеш только устаревших пакетов:
apt autoclean
Удаляет пакеты которые больше не нужны как зависимости:
apt autoremove -y
Очищает кеш DNF (CentOS/AlmaLinux/Rocky):
dnf clean all
Docker — образы, контейнеры, тома
Docker незаметно накапливает гигабайты неиспользуемых образов, остановленных контейнеров, анонимных томов.
Показывает сколько места занимает Docker:
docker system df
Удаляет всё неиспользуемое — остановленные контейнеры, образы без тегов, сети, кеш сборки:
docker system prune -a
Флаг -a удаляет в том числе образы к которым нет запущенных контейнеров. Без флага удаляются только «dangling» образы (без тегов).
Удаляет только неиспользуемые тома (осторожно — данные удалятся безвозвратно):
docker volume prune
Удаляет кеш сборки Docker:
docker builder prune -a
Старые ядра Linux
После обновлений системы старые ядра остаются на диске. На Ubuntu /boot раздел часто маленький и быстро заполняется.
Показывает какие ядра установлены:
dpkg --list | grep linux-image
Текущее ядро — то что выводит uname -r. Остальные можно удалять.
Удаляет старые ядра автоматически оставляя текущее (только Ubuntu/Debian):
apt autoremove --purge -y
На CentOS/AlmaLinux оставляет только последние 2 ядра:
dnf remove $(dnf repoquery --installonly --latest-limit=-2 -q)
Временные файлы
Показывает размер системных временных директорий:
du -sh /tmp /var/tmp
Удаляет файлы из /tmp старше 7 дней:
find /tmp -type f -mtime +7 -delete
Удаляет файлы из /var/tmp старше 30 дней:
find /var/tmp -type f -mtime +30 -delete
Дампы и core files
При падении процессов система может сохранять core dumps — полные дампы памяти процесса. Один файл легко весит несколько гигабайт.
Находит core dump файлы:
find / -name "core" -o -name "core.*" 2>/dev/null | head -20
Показывает где хранятся системные crash dumps:
ls -lh /var/crash/ 2>/dev/null
ls -lh /var/lib/systemd/coredump/ 2>/dev/null
Удаляет все сохранённые core dumps через systemd:
coredumpctl clean
Специфичные ситуации
База данных занимает много места
MySQL и PostgreSQL оставляют за собой много мусора — удалённые записи не сразу освобождают место на диске.
Показывает размер каждой базы данных в MySQL:
mysql -e "SELECT table_schema AS 'Database', ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)' FROM information_schema.tables GROUP BY table_schema ORDER BY 2 DESC;"
Показывает размер каждой базы в PostgreSQL:
psql -c "SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname)) AS size FROM pg_database ORDER BY pg_database_size(pg_database.datname) DESC;"
Дефрагментирует таблицу и возвращает место операционной системе (MySQL, выполняется внутри mysql консоли):
OPTIMIZE TABLE имя_таблицы;
Дефрагментирует всю базу PostgreSQL (внимание: --full блокирует таблицы на время выполнения — запускайте в период минимальной нагрузки):
vacuumdb --all --full
Файлы удалены но место не освободилось
Классическая ловушка — удалили большой файл, df -h всё ещё показывает диск полным. Причина: файл удалён из директории, но процесс держит его открытым и ядро не освобождает блоки.
Находит процессы которые держат удалённые файлы открытыми:
lsof | grep deleted
В выводе видите имя процесса, PID и размер удалённого файла. Решение — перезапустить этот процесс. Он закроет файловый дескриптор, ядро освободит блоки.
Перезапускает сервис который держит удалённый файл (замените nginx на нужный сервис):
systemctl restart nginx
Если не можете перезапустить процесс — можно очистить файл через /proc без перезапуска. Находите PID и дескриптор файла из вывода lsof, затем:
> /proc/PID/fd/ДЕСКРИПТОР
Заполнен отдельный раздел /var или /home
Если у вас несколько разделов и заполнен только один — можно временно создать симлинк с заполненного раздела на раздел где есть место.
Например, /var/log заполнен, но на /home есть место:
Перемещает логи на другой раздел:
mv /var/log /home/var_log_backup
Создаёт символическую ссылку обратно:
ln -s /home/var_log_backup /var/log
Это временное решение. Правильное — расширить раздел или настроить ротацию чтобы не допускать переполнения.
Проверяем результат
После каждого шага очистки проверяем что место освободилось:
df -h
Показывает актуальное состояние. Если место освободилось — сервисы должны восстановить нормальную работу автоматически. Если какой-то сервис завис из-за полного диска — перезапускаете его:
systemctl restart имя-сервиса
Настраиваем мониторинг чтобы не повторялось
Найти и почистить — полдела. Важно настроить оповещения чтобы узнавать о заканчивающемся месте до того как оно кончится.
Простой скрипт с уведомлением на email
Создаёт скрипт мониторинга:
cat > /usr/local/bin/disk-monitor.sh << 'EOF'
#!/bin/bash
THRESHOLD=85
EMAIL="admin@your-domain.com"
df -h | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{print $5 " " $1}' | 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 "Disk $PARTITION is ${USAGE}% full on $(hostname)" | mail -s "DISK ALERT: $PARTITION ${USAGE}%" $EMAIL
fi
done
EOF
chmod +x /usr/local/bin/disk-monitor.sh
Добавляет проверку в cron каждые 30 минут:
echo "*/30 * * * * root /usr/local/bin/disk-monitor.sh" >> /etc/crontab
Настройка автоматической ротации логов
Предотвращает бесконтрольный рост логов Nginx. Создаёт конфиг ротации:
cat > /etc/logrotate.d/nginx-custom << 'EOF'
/var/log/nginx/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
sharedscripts
postrotate
nginx -s reopen
endscript
}
EOF
Параметры: daily — ротация раз в день, rotate 14 — хранить 14 архивов, compress — сжимать старые логи gzip, delaycompress — вчерашний лог не сжимать сразу (нужен для корректного переключения).
Настраивает ограничение размера журнала journald навсегда. Редактирует конфиг:
sed -i 's/#SystemMaxUse=/SystemMaxUse=2G/' /etc/systemd/journald.conf
sed -i 's/#SystemMaxFileSize=/SystemMaxFileSize=200M/' /etc/systemd/journald.conf
systemctl restart systemd-journald
После этого journald никогда не вырастет больше 2 GB.
Ограничивает хранение core dumps системой:
sed -i 's/#Storage=external/Storage=none/' /etc/systemd/coredump.conf
systemctl daemon-reload
Когда нужно расширять диск
Если после всех чисток свободного места всё равно мало — пора расширять. Временное решение это временное: если данные растут, место будет заканчиваться снова.
Показывает текущую разметку дисков:
lsblk
На VPS диск расширяется через панель управления хостинга — добавляете объём к существующему разделу или подключаете дополнительный диск. После этого нужно расширить файловую систему.
Устанавливает утилиту growpart (если ещё нет):
apt install cloud-guest-utils -y # Ubuntu/Debian
dnf install cloud-utils-growpart -y # CentOS/AlmaLinux
Проверяет есть ли нераспределённое место на диске после расширения в панели:
fdisk -l /dev/sda
Расширяет раздел на всё доступное нераспределённое место (для GPT разметки):
growpart /dev/sda 1
Расширяет файловую систему ext4 до размера раздела:
resize2fs /dev/sda1
Для xfs:
xfs_growfs /
После этих команд df -h покажет увеличившийся раздел без перезагрузки.
Часто задаваемые вопросы
Диск полон но я не вижу больших файлов — почему?
Две возможных причины. Первая — файлы удалены но процессы держат их открытыми. Проверяете через lsof | grep deleted и перезапускаете виновный сервис. Вторая — закончились иноды, а не место. Проверяете через df -i: если IUse% равен 100%, ищите директории с огромным количеством мелких файлов (кеши PHP-сессий, очереди сообщений, временные файлы приложений).
Какие директории чистить в первую очередь?
В порядке приоритета: /var/log (логи), /var/lib/docker (если используете Docker), /tmp и /var/tmp (временные файлы), /var/cache/apt или /var/cache/dnf (кеши пакетов), /var/lib/systemd/coredump (core dumps). Эти места дают максимальный эффект при минимальных рисках.
Можно ли удалять файлы в /proc и /sys?
Нет. /proc и /sys — виртуальные файловые системы которые не занимают реального места на диске. Они отображают состояние ядра и процессов в виде файлов. Удалять там ничего не нужно и не нужно пытаться.
Как понять какой процесс активно пишет на диск прямо сейчас?
Используете iotop — показывает I/O активность процессов в реальном времени. Устанавливается через apt install iotop или dnf install iotop. Запустите iotop -o чтобы видеть только процессы с активным I/O. Процесс с максимальным DISK WRITE — тот кто пишет больше всего.
После очистки сайт всё ещё не работает. Что делать?
Некоторые сервисы не восстанавливаются автоматически после того как диск снова стал доступен. Перезапускаете последовательно: веб-сервер (systemctl restart nginx или apache2), базу данных (systemctl restart mysql или postgresql), приложение. Проверяете логи каждого сервиса после перезапуска — там будет видно если есть другие проблемы.
Как не допустить повторения?
Три шага: настройте logrotate для всех сервисов которые пишут логи, ограничьте размер journald в /etc/systemd/journald.conf параметром SystemMaxUse, добавьте мониторинг диска с оповещением на email или в Telegram при заполнении больше 80-85%. Этого достаточно чтобы получать предупреждения за несколько дней до переполнения.
Итоги
Полный диск — решаемая проблема. Последовательность действий: df -h для подтверждения, du -sh /* | sort -rh для поиска виновника, чистка логов и кешей для быстрого освобождения места, настройка мониторинга и ротации чтобы не повторялось.
Большинство случаев решают три команды — очистка кеша пакетов, очистка журнала journald и удаление старых Docker образов. Если этого не хватает — lsof | grep deleted и ncdu помогут найти нестандартную причину.
VPS на THE.Hosting с NVMe дисками в RAID-10 даёт запас по скорости I/O даже когда диск близко к заполнению. При необходимости объём диска расширяется через панель управления без остановки сервера. Поддержка доступна 24/7 через Telegram — помогут и с диагностикой и с расширением раздела.