Лучший способ освободить место на диске от удаленных файлов, которые остаются открытыми

28

Привет У меня есть много файлов, которые были удалены, но по какой-то причине дисковое пространство, связанное с удаленными файлами, не может быть использовано, пока я явно не уничтожу процесс для файла, занимающего место на диске

$ lsof /tmp/
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF      NODE NAME
cron     1623 root    5u   REG   0,21        0 395919638 /tmp/tmpfPagTZ4 (deleted)

Дисковое пространство, занимаемое удаленным файлом выше, вызывает проблемы, такие как при попытке использовать клавишу табуляции для автозаполнения пути к файлу, я получаю ошибку bash: cannot create temp file for here-document: No space left on device

Но после запуска kill -9 1623места для этого PID освобождается, и я больше не получаю ошибку.

Мои вопросы:

  • почему это пространство не освобождается сразу при первом удалении файла?
  • Каков наилучший способ вернуть файловое пространство, связанное с удаленными файлами?

и, пожалуйста, дайте мне знать любую неправильную терминологию, которую я использовал, или любую другую соответствующую и уместную информацию относительно этой ситуации

BryanK
источник

Ответы:

26

В Unix имена файлов - это просто указатели (inode), которые указывают на память, в которой находится файл (это может быть жесткий диск или даже файловая система с поддержкой RAM). Каждый файл записывает количество ссылок на него: ссылки могут быть либо именем файла (во множественном числе, если существует несколько жестких ссылок на один и тот же файл), а также каждый раз, когда файл открывается, процесс фактически содержит «ссылку» на то же самое пространство

Пространство физически освобождается только в том случае, если не осталось ссылок (следовательно, к нему невозможно добраться). Это единственный разумный выбор: пока файл используется, это не важно, если кто-то больше не может получить к нему доступ: вы используете его, и пока вы его не закроете, у вас все еще будет контроль над ним - вы даже не заметите имя файла ушел или переехал или что-то еще. Это даже используется для временных файлов: в некоторых реализациях файл создается и немедленно его отменяется, поэтому он не виден в файловой системе, но процесс, который его создал, использует его как обычно. Flash-плагин особенно любит этот метод: все загруженные видеофайлы остаются открытыми, но файловая система их не показывает.

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

Орион
источник
24

Файлы удаляются из файловой системы, где удаляется любая ссылка на этот индекс. Ссылка может быть на диске (ссылка в любом каталоге) и .. из открытых приложений. Если вы удаляете файл - вы удаляете только ссылку с диска, но - ссылка из приложения остается.

Вы можете «освободить» пространство двумя способами:

  1. как уже упоминалось выше - вы можете убить приложение, которое открывает файл.
  2. Вы можете ... усечь файл. Даже если он удален:

Если вы знаете pid - посмотрите, какие файлы открыты с помощью этого pid: ls -l / proc / PID / fd. Здесь вы видите ссылки вроде:

undefine @ uml: ~ $ ls -l / proc / 18596 / fd
Разем 0
lrwx ------ 1 undefine undefine 64 lut 1 00:06 0 -> / dev / pts / 30
lrwx ------ 1 undefine undefine 64 lut 1 00:06 1 -> / dev / pts / 30
lrwx ------ 1 undefine undefine 64 lut 1 00:05 2 -> / dev / pts / 30
lr-x ------ 1 undefine undefine 64 lut 1 00:06 3 -> / home / undefine / x (удалено)
lr-x ------ 1 undefine undefine 64 lut 1 00:06 4 -> anon_inode: inotify

Как видите - 3 фд удаляется. Вы можете обрезать его командой (например):

undefine @ uml: ~ $:> / proc / 18596 / fd / 3
Undefine @ UML: ~ $ 

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

Undefine
источник
обратите внимание, что после усечения файла исходный процесс, удерживающий его, все еще может добавляться в конец (где он ожидает конца). В результате получаются огромные, но разреженные файлы, которые занимают меньше места на диске (если файловая система поддерживает разреженные файлы) и продолжают расти!
törzsmókus
да. Если что-то записать в файл, это будет происходить на диске. Трудно избежать этого, не останавливая приложение, которое записывает на диск;)
undefine
8

Как уже говорили другие, lsofможно использовать список всех удаленных файлов, которые все еще находятся на диске из-за дескрипторов открытых файлов. Однако это может быть очень длинный список. Вот команда, которая перечисляет эти файлы, отсортированные по возрастанию в байтах:

sudo lsof -F sn0 | tr -d '\000' | grep deleted | sed 's/^[a-z]*\([0-9]*\)n/\1 /' | sort -n

Может быть более краткий способ сделать это, но вышеприведенная команда сработала для меня.

jcoffland
источник
5

Пространство не освобождается сразу, потому что запущенный процесс все еще имеет дескриптор открытого файла для только что удаленного файла. В конце концов, если процесс все еще пытается использовать файл, вы, вероятно, не хотите, чтобы ядро ​​избавилось от него (файла). Это может немного расстроить процесс. Лучший (и единственный, насколько мне известно) способ освободить место - это сделать то, что вы сделали - убить процесс.

Джон
источник
Вероятно, лучшее предложение, чем «как это работает», - «если процесс все еще использует файл, Unix не должен пытаться от него избавиться».
Братчли
Хорошая точка зрения. Я добавил это к ответу.
Джон
-1

(Монетный двор 17.1)

TL; DR:

  • Проверьте с помощью sudo baobab(Анализатор использования дисков).
  • Очистить rootкорзину пользователя.

контекст

Я застрял с постоянно уменьшающимся пространством, в то время как я постоянно удалял файлы. Я установил trash-cliпакет, чтобы очистить корзину, но это не помогло. Наконец, я заметил, что когда я запускал baobab(Disk Usage Analyzer в GUI, по крайней мере, на Mint 17.1) для проверки структуры дискового пространства, он выдавал предупреждение о том, что некоторые папки были недоступны. Так что я побежал в rootиспользовании sudo baobab. Это выявило проблему. Многие файлы, которые были удалены, были в мусорной корзине rootпользователя, а не моего собственного пользователя. Таким образом, я не смог освободить пространство. Затем я просто очистил корзину, используя root ( sudo trash-cli), и все мое пространство вернулось.

Deleet
источник
-1

Попробуйте использовать приведенную ниже команду

lsof | grep deleted

а затем убить pid удаленного файла.

Сумит Тяги
источник
ОП зашел так далеко; это не отвечает на их вопросы.
Джефф Шаллер