¿Cómo recupero espacio libre en archivos eliminados sin reiniciar los procesos de referencia?

12

Cuando se eliminan archivos grandes en un servidor, los archivos aún pueden ser referenciados por procesos, por lo que el sistema de archivos no tiene más espacio libre.

Intenté usar lsof , pero parece que no enumeró los archivos eliminados. fuser -cfuncionó mejor, pero la lista de procesos es demasiado larga para verificarla para cada proceso, especialmente porque cada proceso es un proceso de Oracle.

bash-3.2# fuser -c /var
/var:      105o   29999o   20444c    3528c   27258o    7715o    3864o    3862o    2494o   18205o   17450co   17445co   14912co   14824co   14818co   14816o   14814o    8532c    8530c    7633com    7118o    6958o    6790c    6784co    6734o    6693o    6689o    6684o    6675o    6635o    6594c    6548o    6547o    6546o    6545o    6544o    6543o    6542o    6541o    6540o    6537o    6535o    6456o    6128co    6113o     335o     245co     229o     161o       8o
bash-3.2# du -hs /proc
 139T   /proc

A veces sucede que una aplicación o un usuario elimina un archivo, por ejemplo, un archivo de registro, y que este proceso aún no se puede reiniciar.

¿Existen métodos de bienes para reclamar espacio en disco en archivos eliminados sin reiniciar el proceso que tiene una referencia a este archivo eliminado?

ujjain
fuente
como referencia ... una mejor manera de eliminar un archivo abierto es copiar / dev / null en el archivocp /dev/null file
Mike
@Mike cp /dev/nulles un comando nulo ya que cpno tiene nada que copiar, una simple redirección es estrictamente equivalente :>fileo incluso>file
jlliagre

Respuestas:

12
find /proc/*/fd -ls 2> /dev/null | grep '(deleted)'

Encuentra todos los descriptores de archivos abiertos.

Grep eliminado.

StdError a / dev / null

Salida:

160448715    0 lrwx------   1 user      user            64 Nov 29 15:34 /proc/28680/fd/113 -> /tmp/vteT3FWPX\ (deleted)

O puedes usar awk

find / proc / * / fd -ls 2> / dev / null | awk '/ deleted / {print $ 11}';

salida awk (probado en bash Ubuntu 12.04):

/proc/28680/fd/113

Encuentra y trunca todos los archivos eliminados (probado en bash Ubuntu 12.04):

(NO HAGA ESTO SI NO SABE LO QUE HACE)

find /proc/*/fd -ls 2> /dev/null | awk '/deleted/ {print $11}' | xargs -p -n 1 truncate -s 0

-p pregunta antes de ejecutar truncar

Mejor forma es truncar manualmente

Truncado manual:

: > /proc/28680/fd/113

o:

> /proc/28680/fd/113

o:

truncate -s 0 /proc/28680/fd/113

Disfrutar;)

usuario3439968
fuente
+1, pero también
necesité
6

Aquí hay un ejemplo simple con less:

Supongamos que tenemos un archivo my10MBfile:

$ dd if=/dev/zero of=/tmp/my10MBfile bs=1M count=10
10+0 enregistrements lus
10+0 enregistrements écrits
10485760 octets (10 MB) copiés, 0,0454491 s, 231 MB/s

$ ls -l /tmp/my10MBfile
-rw-r--r-- 1 max max 10485760 avril 23 22:49 /tmp/my10MBfile

$ df -m /tmp
/dev/disk/by-uuid/6835b2fd-971d-420c-ba18-3c729ec2e8a0     14637  9225       4662  67% /

Ahora abro ese archivo con less(sí, es un archivo binario ... no importa)

$ less /tmp/my10MBfile &

$ lsof -p $(pidof less) | grep 10MBfile
less    29351  max    4r   REG    8,3 10485760 521464 /tmp/my10MBfile

Luego elimino ese archivo

$ rm /tmp/my10MBfile

$ lsof -p $(pidof less) | grep 10MBfile
less    29351  max    4r   REG    8,3 10485760 521464 /tmp/my10MBfile (deleted)

$ df -m /tmp
/dev/disk/by-uuid/6835b2fd-971d-420c-ba18-3c729ec2e8a0     14637  9225       4662  67% /

Todavía está allí, pero borrado. Mire la cuarta columna de la salida de lsof: Descriptor de archivo número 4 abierto para lectura (4r)

¡Vamos a ejecutar GDB!

$ gdb -p $(pidof less)

GNU gdb (GDB) 7.4.1-debian
....
Attaching to process 29351
....

(gdb) p close(4)
$1 = 0
(gdb) q

¡Eso es!

$ df -m /tmp
/dev/disk/by-uuid/6835b2fd-971d-420c-ba18-3c729ec2e8a0     14637  9215       4672  67% /

Nuestros 10 MB son bienvenidos :)

$ ls /proc/29351/fd
0  1  2  3

$ ps 29351
29351 pts/0    S+     0:00 less /tmp/my10MBfile

El proceso aún se está ejecutando.

maxxvw
fuente
2
Ok, pero por cuanto tiempo? muchos procesos simplemente salen si no pueden escribir en su archivo de registro.
cuello largo
¿Logrotate no puede hacer esto por usted?
maxxvw
logrotate envía al proceso una señal para cerrar el archivo de registro y abrir uno nuevo.
cuello largo
2

Este comando mostrará todos los archivos eliminados aún abiertos en un sistema Solaris:

find /proc/*/fd -type f -links 0

Puede truncar los que está seguro que desea con este comando:

:> /proc/p/fd/x

siendo p el id del proceso yx el descriptor de archivo devuelto por el primer comando.

No se preocupe si con algunos programas el tamaño reportado lsse restablece al tamaño antes del truncamiento después de un tiempo, el tamaño real utilizado en el disco será mucho menor ya que el archivo ahora es escaso.

jlliagre
fuente
0

Puede intentar ir al /proc/<pid>/fddirectorio y truncar el descriptor de archivo correspondiente. Digamos que fd = 3 puntos al archivo eliminado de pid == 123:

# echo "" >! /proc/123/fd/3
kofemann
fuente
¿tienes un ejemplo de dónde funciona este método? No puedo encontrar una manera de alterar FD desde allí
maxxvw
Sí, esto funciona, pero ¿cómo encontrar el pid del proceso?
ujjain
-2

Ninguna de estas soluciones funcionó para mí. Solo después de usar Bleachbit como root pude liberar adecuadamente el espacio asociado con los archivos eliminados.

usuario189721
fuente