Обложка канала

ServerAdmin.ru

12437 @srv_admin

Авторская информация о системном администрировании.

ServerAdmin.ru

4 года назад
Открыть в
В продолжение к предыдущей заметке, где я восстанавливал удалённый файл, который был открыт процессом. Ещё один практический пример на эту тему. Мы теперь знаем, что в Linux сначала удаляется имя файла. Сам же файл удаляется, только после того, как счётчик ссылок станет равен нулю и будут закрыты все файловые дескрипторы, ассоциированные с файлом. Давайте найдём файлы, количество ссылок которых равны нулю. # lsof +L1 или так: # lsof | grep '(deleted)' Вывод этой команды можно ограничить файлами конкретного раздела: # lsof -s +L1 -a /dev/sda1 Приведу практический пример по этой теме. Создадим большой файл /tmp/tempfile размером в один гибибайт: # dd if=/dev/zero of=/tmp/tempfile bs=1M count=1024 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 2.22636 s, 482 MB/s Находясь в директории /tmp запускаю команду в фоне, которая открывает файл на чтение. Удаляет его и засыпает. Используется оболочка Bash: # ( : {fd}< ./tempfile && rm -f ./tempfile && sleep 30000 {fd}>&- ) 2> /dev/null & Если после запуска скрипта посмотреть размер раздела, на котором размещается директория /tmp и сумму всех файлов на этом разделе, то получится разница в этот самый гибибайт. В моём случае это корневой раздел: # df -h / Filesystem           Size Used Avail Use% Mounted on /dev/mapper/debian11--vg-root  19G 2.1G  16G 12% / # du -xhs / 1.1G / Есть процесс, который удалил файл, но продолжает держать открытым файловый дескриптор, поэтому реально файл не удалён и всё ещё занимает место на диске. Если поднять процесс из фона и завершить, то файловый дескриптор будет закрыт и файл перестанет заниматься место на диске. # fg CTRL+C На практике я регулярно сталкиваюсь с подобной ситуацией. Чаще всего это касается лог файлов. Кто-то решает удалить распухший лог, но при этом забывает перезапустить сервис. Например некоторые разработчики любят урезать логи docker или nginx с помощью truncate. В итоге лог вроде как удалён, но файловый дескриптор открыт и служба продолжает писать в него логи. Доходит до того, что всё место на диске занято и непонятно кем. Тут спасёт перезагрузка, или определение с помощью lsof какой файл открыт и какая служба его держит. Перезапускаем и всё становится в порядке с местом. #terminal