2 votos

Las utilidades de directorio del shell de MacOSX son muy lentas con directorios grandes (millones de archivos), ¿alguna alternativa?

Debido a un problema con la sincronización de los contactos (no estoy seguro de cuál fue el origen del problema, probablemente una caída del programa en el corte de energía, que causó inconsistencia en el archivo de la base de datos de los contactos), el proceso de sincronización creó casi 7M de archivos en Images/ :

hostname:Images username$ pwd
/Users/username/Library/Application Support/AddressBook/Sources/4D81D34B-C932-4578-8A31-4E2E244B3875/Images

hostname:Images username$ ls
^C

hostname:Images username$ ls | wc -l
 6797073
(the result was after hours)

hostname:Images username$ cd ..
hostname:4D81D34B-C932-4578-8A31-4E2E244B3875 username$ ls -l
total 600224
-rw-r--r--@     1 username  staff     409600 Aug  2 17:43 AddressBook-v22.abcddb
-rw-r--r--@     1 username  staff      32768 Aug  3 00:13 AddressBook-v22.abcddb-shm
-rw-r--r--@     1 username  staff    2727472 Aug  2 23:26 AddressBook-v22.abcddb-wal
drwx------  65535 username  staff  231100550 Aug  2 23:26 Images
-rw-r--r--@     1 username  staff      45056 Dec  7  2017 MailRecents-v4.abcdmr
-rw-r--r--@     1 username  staff      32768 Dec  7  2017 MailRecents-v4.abcdmr-shm
-rw-r--r--@     1 username  staff       4152 Dec  7  2017 MailRecents-v4.abcdmr-wal
drwx------      5 username  staff        170 Feb 26 18:51 Metadata
-rwxr-xr-x      1 username  staff          0 Dec  7  2017 OfflineDeletedItems.plist.lockfile
-rwxr-xr-x      1 username  staff          0 Dec  7  2017 Sync.lockfile
-rwxr-xr-x      1 username  staff          0 Dec  7  2017 SyncOperations.plist.lockfile

Cuando intenté utilizar las herramientas del shell ( ls , find ), no obtuve ningún resultado en tiempo razonable para el trabajo interactivo (fueron horas), independientemente de desactivar la clasificación de archivos como ls -f (lo que parece ayudar en el caso de otros sistemas operativos tipo UNIX ), etc. El ls ha crecido hasta alrededor de 1GB de tamaño y ha trabajado durante HORAS antes de dar algún resultado. Mi pregunta es: ¿me falta alguna opción complicada para que esto funcione de forma razonable para directorios grandes (con salida de los resultados en el camino, por ejemplo, para procesar más, filtrar, etc.) o estas herramientas simplemente no están escritas a escala? ¿O tal vez hay mejores utilidades de archivo/directorio para MacOSX? (No he probado ninguna aplicación GUI en ese directorio, pensando que es mejor no hacerlo...).

He escrito un programa en C bastante trivial que lee las entradas de los directorios y que emite la información en el camino:

#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <unistd.h>

int main ( const int argc,
           const char * const * argv )
{
    const char * const dirpath = argv[1];
    DIR *dirp = opendir ( dirpath );
    if ( dirp == NULL )
        return (-1);

    int count = 0;
    struct stat statbuf;

    for ( struct dirent *entry = readdir ( dirp ) ;
      entry != NULL ;
      entry = readdir ( dirp ), count++ )
    {
       char filepath [ PATH_MAX + 1 ];
       memset ( filepath, 0, PATH_MAX );
       strncat ( filepath, dirpath, PATH_MAX );
       strncat ( filepath, "/", PATH_MAX );
       strncat ( filepath, entry->d_name, PATH_MAX );
       stat ( filepath, &statbuf );
       printf ("%s %llu\n", entry->d_name, statbuf.st_size );
    }
    closedir ( dirp );
    printf ("%d", count );

    return 0;
}

que realmente funciona (muestra el resultado después de leer cada entrada) y tiene una huella de memoria de alrededor de 300K. Así que no es un problema del sistema operativo (sistema de archivos, controlador, biblioteca estándar o lo que sea), sino de las herramientas que básicamente no escalan bien (sé que soportan más opciones, etc., pero para un listado de directorios básico, sin ordenar ni nada de fantasía ls debería funcionar mejor, es decir, no asignar 1GB de memoria, mientras que find debería hacer la acción para cada entrada que encuentra (y coincide), no leerlas todas primero, como aparentemente hace...).

¿Alguien ha experimentado esto y tiene una buena solución para lidiar con directorios tan grandes (qué utilidades usar) en MacOSX? (¿O quizás sea necesario escribir alguna utilidad de sistema personalizada en este caso?)

(Es una situación excepcional, por supuesto, ocurrió por primera vez en mi sistema - pero el sistema operativo soporta directorios tan grandes, y las herramientas básicas del shell deberían tratar con ellos en un razonable manera...)

EDITAR: Pequeña corrección en el programa (a la ruta del archivo le faltaba '/').

2voto

t-w Puntos 41

Así parece, me respondo a mí mismo, tal vez alguien encuentre útiles mis conclusiones.

Las herramientas estándar de Unix (MacOSX, Linux) no sirven para gestionar directorios en situaciones tan extremas como las descritas. Son muy eficientes (tal vez lo más eficiente posible en lo que hacen) en situaciones normales - pero este diseño conduce a un gran uso de memoria (en GBs) y un tiempo muy largo para obtener cualquier resultado cuando un directorio contiene millones de archivos. Por ejemplo, ls leer primero todas las entradas del directorio (tan rápido como sea posible), y sacarlas de una lista/matriz en memoria - parece ser la forma más eficiente para dicha tarea. Sin embargo, para casos extremos (con millones de archivos), este enfoque falla en el uso práctico, por ejemplo, no es posible aprender nada sobre el contenido del directorio durante horas (como fue en mi caso).

Desde un punto de vista práctico, sería bueno que estas herramientas tuvieran una opción para activar el procesamiento "en flujo": procesar las entradas en cantidades manejables, por ejemplo, en racimos de 1000 entradas (si una por una sería demasiado lento).

Por ahora, parece necesario crear una utilidad de sistema personalizada que haga el trabajo, es decir, listar / eliminar / mover los archivos en dicho directorio. Se podría hacer probablemente algo más que C (Python, Perl), pero ya que podría ser más lento, por lo que no aconsejaría esto (incluso pequeño tiempo multiplicado por millones puede ser significativo en general).

Parece que los usuarios no técnicos no tienen suerte aquí, tienen que pedir ayuda.

Una cosa que puede ser interesante de notar aquí es que la relación del tiempo requerido para las operaciones en un directorio vs. el número de archivos en él es no lineal (este caso es el HFS de MacOS, otros sistemas de archivos pueden variar en ambos sentidos). Borrar los 6,7M de archivos usando el programa de arriba (sólo "desvinculando" en vez de imprimiendo) me llevó unos días (en un iMac antiguo con un HDD, no un SSD). Estuve registrando los nombres de los archivos a medida que se iban eliminando - al principio, el ritmo era de unos 100K archivos al día, mientras que eliminar los últimos 1-1,5 millones llevó unas 3 horas.

Gracias por los comentarios.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X