Назад | Перейти на главную страницу

На сервере Linux не хватает места

Мне задавали этот вопрос в двух последовательных интервью, но после некоторых исследований и проверки с различными системными администраторами я не получил хорошего ответа. Мне интересно, может ли кто-нибудь помочь мне здесь.

Серверу не хватает места на диске. Вы замечаете очень большой файл журнала и решаете, что его можно безопасно удалить. Вы удаляете файл, но диск по-прежнему показывает, что он заполнен. Что могло бы вызвать это и как бы вы это исправить? И как узнать, какой процесс пишет этот огромный файл журнала?

Это распространенный вопрос на собеседовании и ситуация, которая возникает в различных производственных средах.

Записи каталога файла были удалены, но процесс регистрации все еще продолжается. Операционная система не будет освобождать пространство до тех пор, пока все дескрипторы файлов не будут закрыты (например, процесс не будет убит) и все записи каталога не будут удалены. Чтобы найти процесс записи в файл, вам нужно использовать lsof команда.

Другая часть вопроса иногда может быть такой: «Как очистить файл, в который выполняется запись, не прерывая процесс?» В идеале вы бы "ноль" или "усечение" файла журнала с чем-то вроде : > /var/log/logfile вместо удаления файла.

Есть еще одна ссылка на файл (либо жесткая ссылка, либо дескриптор открытого файла). При удалении файла удаляется только запись в каталоге; данные файла и индексный дескриптор остаются до тех пор, пока последняя ссылка на него не будет удалена.

Довольно часто служба создает временный файл и немедленно удаляет его, оставляя файл открытым. Это создает файл на диске, но гарантирует, что файл будет удален, если процесс завершится ненормально, а также предохраняет другие процессы от случайного доступа к файлу. MySQL делает это, например, для всех своих временных таблиц на диске. Вредоносные программы часто используют аналогичную тактику, чтобы скрыть свои файлы.

В Linux вы можете легко получить доступ к этим удаленным файлам как /proc/<pid>/fd/<filenumber>.

Я не системный администратор, но из того, что я собрал на Unix.SE, система Linux фактически не удаляет файл (отметьте пространство как свободное / многоразовое) после того, как он будет отсоединен, пока все дескрипторы файлов, указывающие на них, не будут был закрыт. Итак, чтобы ответить на первую часть, место еще не освободилось, потому что процесс все еще его читает. Чтобы ответить на второй вопрос, вы можете увидеть, какой процесс использует файл с lsof.

Один альтернативный ответ, помимо очевидного ответа о жесткой ссылке / открытии файла: этот файл является (очень) разреженным файлом, например /var/log/lastlog на RHEL, который на самом деле не занимал так много места. Его удаление почти не повлияло, поэтому вам нужно посмотреть следующий по размеру файл.

Если процесс, записывающий файл, является корневым, он будет записывать в зарезервированное файловое пространство суперпользователя. В файловой системе есть это пространство для поддержания работоспособности системы в случае заполнения диска пользовательской задачей. Это пространство (imho по умолчанию 5%) невидимо для многих инструментов.

lsof может показать вам, какой процесс заблокировал файл, следовательно, пишет в него.

Помимо того, что файл открывается процессом, второй случай - это когда у вас есть файловая система, которая поддерживает снимки, например btrfs или ZFS.

Например, вы делаете снимок с существующим огромным файлом журнала. Если вы удалите файл сейчас, вы удалите только дельту. И дельта удаляется только тогда, когда файл не используется.

Смотрите также:

Третий случай - это когда у вас есть файловая система, которая поддерживает дедупликацию на уровне блоков, и большая часть файла идентична другому файлу. Я не ожидаю, что это произойдет с журналом, если у вас нет контейнера или виртуальной машины, которая отправляет журналы в контейнер системного журнала или виртуальную машину, которые используют одну и ту же FS, так что содержимое журнала идентично.