2012-04-04 19 views
5

Tengo 8 millones de archivos en my/tmp y necesito eliminarlos. Este servidor también está ejecutando una aplicación bastante importante y no puedo sobrecargarla.Eliminar gran cantidad de archivos

estoy usando pequeño script php:

<?php 
$dir = "/tmp"; 
$dh = opendir($dir); 
$i = 0; 
while (($file = readdir($dh)) !== false) { 
    $file = "$dir/$file"; 
    if (is_file($file) && (preg_match("/open/", $file))) { 
    unlink($file); 
    #echo $file; 
    if (!(++$i % 10000)) { 
     echo "$i files removed\n"; 
    } 
    } 
} 
?> 

pero hace que mi aplicación inalcanzable, incluso con: $ ionice -c 3 php ./tmp_files_killer.php $ nice -n 20 php ./ tmp_files_killer.php

he cambiado de secuencia de comandos para que no se lea/tmp dir todo el tiempo:

$ ls -1 /tmp > tmp_files_list.txt 

<?php 
$file = "tmp_files_list.txt"; 
$infile = fopen($file, "r"); 

while (!feof($infile)) { 
    $line = rtrim(fgets($infile), "\n\r"); 
    if ($line != null){ 
    $file = "$dir/$line"; 
    unlink($file); 
    if (!(++$i % 10000)) { 
     echo "$i files removed\n"; 
    } 
# echo $line + "\n"; 
    } 
} 
?> 

pero la ejecución de este script también se ralentiza mi aplicación El proceso no carga la CPU y tengo suficiente memoria.

Chicos, cómo eliminar estos archivos?

+0

¿No puedes hacerlo en la línea de comandos? ¿Tienes que borrarlos solo una vez, o en intervalos regulares? Tal vez creando un cronjob que borre una cantidad fija de archivos a intervalos regulares. – pritaeas

Respuesta

0

Hice este tipo de cosas cuando quería limpiar un directorio de carga para una galería. Fue realmente largo ... Así que decidí probar exec() como comandos con el comando rm /path/to/clean/* y se puso realmente rápido.

No muy limpio, pero al menos, funcionó bien para mí.

3

si se puede ejecutar directamente comandos en terminal de Linux, entonces esto se convertirá en proceso muy fácil, ejecutar directamente este comando

find /tmp -type f -exec rm -v {} \; 

, además, si se desea llevar a cabo este proceso periódicamente a continuación, se puede configurar una tarea programada para funcionar a medianoche, donde su servidor casi estará inactivo

+0

También probaría esto primero, pero aún puede perjudicar al servidor. –

+0

Tenga en cuenta que esto perderá archivos que no tienen un '.' en su nombre. – sarnold

+1

.. Además, el '-exec' causará alrededor de mil veces o más llamadas al sistema 'execve (2)' de lo necesario. 'encontrar ... -print0 | xargs -0 rm' ejecutaría 'rm' significativamente menos a menudo. Y la salida ('-V') es sólo va a causar innecesaria IO, que a menudo es la parte más lenta de los programas ... – sarnold

0

¿Hay una necesidad de hacer la limpieza mediante el uso de un script php?

Si no es así, echar un vistazo a este article ... debe conseguir que algunas ideas

4

usted podría conseguir la secuencia de comandos para operar en "trozos", luego dormir entre cada trozo.

En su segunda versión, podría agregar un sleep() después del eco, digamos 30 segundos. Si sintoniza la cantidad de archivos eliminados y el tiempo que durmió, debe mantener el servidor receptivo mientras sigue funcionando adecuadamente.

En el futuro, debe ejecutar un trabajo de limpieza regularmente desde cron para evitar llegar a este punto.

1

Resolvería esto de otra manera: destruir todo el sistema de archivos de una vez.

Crear un nuevo sistema de archivos - podría ser un sistema de archivos simple tmpfs, podría ser un sistema de archivos ext2 o ext3 viviendo en un archivo montado en bucle, podría ser una unidad nueva (memoria USB?), Cualquier cosa.

Entonces mv la /tmp punto de montaje a otro nombre, montar el nuevo sistema de ficheros en /tmp y ejecute mke2fs en la particiónque solía ser /tmp, y escribir todo un nuevo sistema de archivos limpia desde cero.

Una vez que se vuelve a crear el dispositivo antiguo-tmp, puede realizar los pasos de nuevo - mv /tmp /new-tmp, copia de los datos que deben ser persistentes, mount el dispositivo de re-formateado de nuevo en /tmp,, y copia de los datos que deben persistir.

0

Esta es probablemente la manera todavía más rápido estándar para eliminar todos los archivos en/tmp:

find /tmp -type f -exec rm {} + 

con GNU encontrar, esto podría ser un poco más rápido:

find /tmp -type f -delete 

Si/tmp está en su propio sistema de archivos, simplemente desmonte y mkfs. Si es tmpfs, solo reinicie.

Cuestiones relacionadas