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


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 звільняється, і я більше не отримую помилки.

Мої запитання:

  • чому цей простір не одразу звільняється при першому видаленні файлу?
  • який найкращий спосіб повернути файловий простір, пов’язаний із видаленими файлами?

і, будь ласка, повідомте мені про будь-яку невірну термінологію, яку я використав, або будь-яку іншу релевантну інформацію, що стосується цієї ситуації.

Відповіді:


26

Унісе, назви файлів - це лише вказівники (inode), які вказують на пам'ять, де знаходиться файл (який може бути жорстким диском або навіть файловою системою, підтримуваною ОЗУ). Кожен файл записує кількість посилань на нього: посилання можуть бути як ім'ям файлу (множиною, якщо на одному файлі є декілька жорстких посилань), а також кожного разу, коли файл відкривається, процес фактично містить "посилання" на той самий простір.

Простір фізично звільняється лише в тому випадку, якщо не залишилося жодних зв’язків (тому дістатися до нього неможливо). Це єдиний розумний вибір: поки файл використовується, не важливо, чи хтось інший більше не може отримати до нього доступ: ви користуєтесь ним, і поки ви не закриєте його, ви все ще маєте контроль над ним - ви навіть не помітите ім'я файлу пішла чи переїхала чи що завгодно. Це навіть використовується для тимчасових файлів: деякі реалізації створюють файл і негайно відключають його, тому він не видно у файловій системі, але процес, який створив, використовує його нормально. Особливо полюбляє цей плагін Flash-модуль: усі завантажені відеофайли зберігаються відкритими, але файлова система їх не показує.

Отже, відповідь полягає в тому, що, поки у процесах файли все ще відкриті, ви не повинні сподіватися повернути простір. Це не звільняється, його активно використовують. Це також одна з причин того, що програми дійсно повинні закривати файли, коли вони закінчують їх використання. При звичайному використанні ви не повинні вважати цей простір вільним, і це також не повинно бути дуже поширеним - за винятком тимчасових файлів, які спеціально не пов’язані між собою, насправді не повинно бути файлів, які ви б вважати невикористаним, але все ще відкритим. Спробуйте перевірити, чи є процес, який робить це багато, і подумайте, як ви його використовуєте, або просто знайдіть більше місця.


24

Файли видаляються з файлової системи, де видаляються будь-які посилання на цей індекс. Довідка може бути на диску (посилання в будь-якому каталозі) та .. з відкритих додатків. Якщо ви видалите файл - ви видалите лише посилання з диска, але - все ще є посилання з програми.

Ви можете "звільнити" простір двома способами:

  1. як було сказано вище - ви можете вбити програму, яка відкриває файл.
  2. ви можете ... усікати файл. Навіть якщо його видалено:

Якщо ви знаєте pid - подивіться, які файли відкриваються цим pid: ls -l / proc / PID / fd ви бачите тут посилання типу:

undefine @ uml: ~ $ ls -l / proc / 18596 / fd
razem 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 fd видалено. ви можете усікати його за допомогою команди (наприклад):

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

Пам'ятайте, що якщо програма читається з цього файлу - це може бути для них небезпечно. Але - якщо це лише файл журналу - ви можете безпечно усікати його.


зауважте, що після обрізання файлу оригінальний процес його утримання все ще може додаватися до кінця (там, де він очікує закінчення). результат здається величезним, але розрідженим файлом, який займає менше місця на диску (якщо файлова система підтримує рідкі файли), і вони все ще ростуть!
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

Можливо, є більш складний спосіб зробити це, але вищезгадана команда працювала для мене.


5

Простір не одразу звільняється, оскільки запущений процес все ще має відкриту ручку файлу для щойно видаленого файла. Зрештою, якщо процес все ще намагається використовувати файл, ви, ймовірно, не дуже хочете, щоб ядро ​​його позбулося (файл). Це може трохи засмутити процес. Найкращий (і єдиний, наскільки я знаю) спосіб звільнити простір - це зробити саме те, що ви зробили - вбити процес.


Можливо, краще речення, ніж "просто як це працює" - "якщо процес все ще використовує файл, Unix не повинен намагатися його позбутися".
Братчлі

Влучне зауваження. Я додав це до відповіді.
Іоанн

-1

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

TL; DR:

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

Контекст

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


-1

Спробуйте скористатися командою нижче

lsof | grep deleted

а потім знищити під-файл видаленого файлу.


ОП так далеко; це не відповідає на їх запитання.
Джефф Шаллер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.