Диск заполнен на Linux сервере: как найти и освободить место
Когда на Linux сервере заканчивается место на диске, всё начинает ломаться непредсказуемо: базы данных отказываются писать, журналы замолкают, обновления пакетов обрываются на середине. Это руководство для всех, кто администрирует Linux сервер или VPS. Оно показывает, как найти, что на самом деле съедает место, как безопасно его освободить и какие файлы трогать нельзя.
Сначала выясните, что именно заполнено
Начните с двух команд:
df -h df -i
Первая показывает занятое место по файловым системам, вторая показывает использование inode. Если df -h сообщает о свободных гигабайтах, а приложения всё равно выдают "No space left on device", скорее всего закончились inode, а не байты. Почти всегда причина в миллионах мелких файлов: PHP сессии, фрагменты кеша, файлы очередей. В этом случае решение в удалении лавины файлов, и диск большего размера не помог бы.
Обратите внимание и на то, какая точка монтирования заполнена. Полный /var на отдельном разделе требует другого пути очистки, чем полная корневая файловая система, и очистка не того места ничего не даст.
df показывает полный диск, du не согласен: удалённые, но открытые файлы
Классическая ловушка: du -sh / находит 40 GB файлов, а df утверждает, что занято 75 GB. Разница обычно приходится на файлы, которые были удалены, пока какой-то процесс держал их открытыми. Ядро не может освободить блоки, пока не закрыт последний файловый дескриптор. Типичная история: кто-то удалил огромный лог через rm, а сервис продолжил писать в уже невидимый файл.
lsof -nP +L1
Команда выводит открытые файлы с нулевым числом ссылок вместе с процессом и файловым дескриптором, которые их держат. Перезапуск или перезагрузка конфигурации сервиса освобождает место сразу:
systemctl restart nginx
Если перезапустить сервис прямо сейчас нельзя, обрежьте удалённый файл через /proc, подставив PID и номер FD из вывода lsof:
: > /proc/1234/fd/4
Ещё одна причина того же симптома: данные, скрытые под точкой монтирования. Если задание резервного копирования однажды писало в /mnt/backup, пока диск для копий не был примонтирован, эти файлы лежат в корневой файловой системе и не видны, пока поверх примонтирован диск. Отмонтируйте и посмотрите, либо примонтируйте / через bind mount в другое место и проверьте там.
Пройдитесь по дереву с ncdu
Для всего остального ncdu остаётся самым быстрым способом увидеть, куда ушло место:
apt install ncdu ncdu -x /
Флаг -x удерживает его в одной файловой системе, чтобы сетевые монтирования и другие разделы не искажали цифры. Навигация стрелками, каталоги отсортированы по размеру, а клавиша d удаляет выбранный элемент, поэтому обращайтесь с ней осознанно. Если диск настолько полон, что пакеты не устанавливаются, обычный du делает ту же работу, только с большим количеством ввода:
du -xh --max-depth=1 / 2>/dev/null | sort -h
Спускайтесь в самый большой каталог и повторяйте, пока не найдёте виновника.
Обычные подозреваемые и как их безопасно почистить
Journald и журналы приложений
journalctl --disk-usage journalctl --vacuum-size=200M
Vacuum удаляет только архивные записи журнала, поэтому он безопасен. Чтобы ограничить журнал навсегда, задайте SystemMaxUse=200M в /etc/systemd/journald.conf и перезапустите systemd-journald. Среди обычных файлов в /var/log ищите лог, который растёт заметно быстрее остальных: стремительно растущий лог означает, что какое-то приложение падает по кругу, и настоящее исправление там, а не в удалении улик. Проверьте, что logrotate действительно работает, и никогда не удаляйте открытый лог-файл, вместо этого обрежьте его:
truncate -s 0 /var/log/huge.log
Кеш apt и старые ядра
du -sh /var/cache/apt apt-get clean apt-get autoremove --purge
apt-get clean всегда безопасен: он удаляет только скачанные файлы пакетов. autoremove --purge удаляет и старые ядра, которые нередко занимают несколько гигабайт в /boot и /usr/lib/modules. Перед подтверждением выполните uname -r и убедитесь, что работающее ядро не попало в список на удаление. Оставьте текущее ядро и один заведомо рабочий запасной вариант.
Образы, контейнеры и тома Docker
docker system df docker system prune
Первая команда показывает, сколько места занимают образы, контейнеры, тома и кеш сборки. Обычный prune удаляет остановленные контейнеры, неиспользуемые сети и висячие образы, что как правило безопасно. Опасные варианты: prune -a, который удаляет каждый образ, не используемый работающим контейнером, и всё, что касается томов. В томах живут данные баз: выполните docker volume ls и удаляйте том только тогда, когда можете сказать, чему он принадлежит.
Core dump и почтовые очереди
coredumpctl list du -sh /var/lib/systemd/coredump /var/crash
Регулярно падающая программа может оставить гигабайты дампов. Старые можно удалить; чтобы остановить рост, ограничьте их в /etc/systemd/coredump.conf и почините то, что падает. Поищите также файлы core.* в рабочих каталогах приложений.
mailq | tail -1 du -sh /var/spool/postfix
Забитая почтовая очередь обычно означает, что веб-форму используют для спама или скрипт по кругу шлёт письма об ошибках. Сначала устраните источник. Затем postsuper -d ALL опустошит очередь, но он удалит и легитимную исходящую почту, поэтому прочитайте очередь перед очисткой.
Что удалять нельзя
- Каталоги баз данных вроде
/var/lib/mysqlили/var/lib/postgresql. Место там освобождают, удаляя данные средствами самой базы, никогда черезrm. - Ничего внутри
/var/lib/dockerвручную. Используйте команды docker, иначе повредите состояние драйвера хранения. /proc/kcoreи другие файлы в/procили/sys. Они выглядят огромными, но места на диске не занимают вовсе.- Работающее ядро и каталог его модулей.
- Открытые лог-файлы. Их удаление лишь воспроизводит описанную выше проблему невидимого открытого файла.
Если сомневаетесь, перенесите файл на другую файловую систему вместо удаления, убедитесь, что ничего не сломалось, и только потом удаляйте.
Предотвратите следующий инцидент
Настройте оповещение мониторинга на 80 процентах заполнения, чтобы решать проблему спокойно, а не на 100 процентах. Ограничьте journald, проверьте, что logrotate покрывает каждый лог ваших приложений, и включите apt-get clean и осторожный docker prune в ежемесячную рутину, которую выполняете осознанно, а не вслепую из cron. А если данные растут просто потому, что растёт проект, очистка не тот инструмент: диску, который постоянно занят выше 90 процентов, нужно больше места, а не больше удалений. На наших VPS серверах в дата-центре в Риге дисковое пространство можно расширить без переустановки, что обычно дешевле часов, потраченных на охоту за последним гигабайтом.
Читайте дальше
Готовы начать?
Запустите за минуты или обсудите с инженером, что подходит вашему проекту.