Elimine en masa un directorio grande en un ZFS sin atravesarlo recursivamente

9

Quiero eliminar un directorio que tiene grandes cantidades de datos. Esta es mi matriz de respaldo, que es un sistema de archivos ZFS , span lineal, grupo único llamado "san". San está montado, /san así que quiero eliminar a granel / san / thispc / CertainFolder

$ du -h -d 1 certainFolder/
1.2T    certainFolder/

En lugar de tener que esperar, rm -rf certainFolder/¿no puedo simplemente destruir el identificador de ese directorio para que pueda sobrescribirse (incluso con el mismo nombre de directorio si elijo recrearlo)?

Entonces, por ejemplo, no saber mucho acerca de la administración interna de zfs fs específicamente cómo mapea los directorios, pero si encontré ese mapa, por ejemplo, y quité las entradas correctas para, por ejemplo, el directorio ya no se mostraría y ese espacio que el directorio tenía anteriormente tiene que ser eliminado de algún tipo de auditoría también.

¿Hay una manera fácil de hacer esto, incluso si está en una ext3 fs, o es eso lo que el comando de eliminación recursiva tiene que hacer en primer lugar, es decir, robar y editar diarios?

Solo espero hacer algo similar kill thisDira donde simplemente elimina algún tipo de ID, y el directorio ya no aparece ls -lay los datos todavía están allí en la unidad, obviamente, pero el espacio ahora se reutilizará ( sobrescrito), porque ZFS es tan genial?

Quiero decir, creo que zfs es realmente genial, ¿cómo podemos hacerlo? ¿Idealmente? frotándose las manos juntas :-)

Mi caso de uso específico (además de mi amor por zfs) es la administración de mi archivo de respaldo. Este directorio de respaldo se envía a través de freefilesync (AWESOME PROG) en mi cuadro de Windows a un recurso compartido de archivos smb, pero también tiene un directorio de versión donde van los archivos antiguos. Estoy eliminando directorios de nivel superior que residen en la copia de seguridad principal, que se copiaron a la versión, por ejemplo /san/version/someStuff, como una limpieza bimensual de rm -rf /san/version/someStuff/*un terminal de masilla, ahora tengo que abrir otro terminal; no quiero hacer eso cada vez, estoy cansado de tener que controlar inútilmente rm -rf.

Quiero decir, tal vez debería configurar el comando para simplemente soltar el controlador, luego imprimir en std, eso podría ser bueno. De manera más realista , zfs destroy san/version; zfs create -p -o compression=on san/versionvuelva a crear el conjunto de datos en unos segundos después de los pensamientos de la respuesta de @Gilles.

Brian Thomas
fuente
FYI, ejecuté este comando para hacer los conjuntos de datos que estoy usando actualmente ... 'zfs create dataset -p -o compression=on yourPoolName/BackupRootDir/hostNameYourPc/somesubdir
Brian Thomas
Acepte una respuesta si uno resolvió el problema descrito en su pregunta original. El problema que acaba de agregar a su pregunta parece ser bastante diferente, por lo que realmente debería plantearse en una nueva pregunta.
jlliagre

Respuestas:

12

El seguimiento de los bloques liberados es inevitable en cualquier sistema de archivos decente y ZFS no es una excepción . Sin embargo, hay una manera simple bajo ZFS de tener una eliminación de directorio casi instantánea "diferiendo" la limpieza subyacente. Técnicamente es muy similar a la sugerencia de Gilles, pero es inherentemente confiable sin requerir código adicional.

Si crea una instantánea de su sistema de archivos antes de eliminar el directorio, la eliminación del directorio será muy rápida porque no será necesario explorar / liberar nada debajo de ella, toda referencia a la instantánea. Luego puede destruir la instantánea en segundo plano para que el espacio se recupere gradualmente.

d=yourPoolName/BackupRootDir/hostNameYourPc/somesubdir
zfs snapshot ${d}@quickdelete && { 
    rm -rf /${d}/certainFolder
    zfs destroy ${d}@quickdelete & 
}
jlliagre
fuente
ok, no he estado familiarizado con las instantáneas. Eso podría ayudarme. He estado borrando / moviendo todo el día todavía. Creé conjuntos de datos no solo para el directorio principal de respaldo, sino también para los directorios de nivel superior en el interior, cada uno comenzando con el nombre de host y algunos niveles superiores ..., por lo que tengo un poco de flexibilidad para destruir y recrear un grupo, pero no es perfecto , ya que no siempre quiero eliminar todo este directorio de grupo, tendría que crear aún más, y eso es una gran cantidad de creación de conjuntos de datos, ¡así que me gusta su sugerencia por ese motivo!
Brian Thomas
44
Si está disponible, feature@async_destroytambién podría ayudar a acelerar esto (desde la perspectiva de un usuario o administrador) si está habilitado; ver zpool get all $pool. Tenga en cuenta que al menos lo miré por última vez, si hay una destrucción pendiente en progreso en la importación del grupo , entonces esa destrucción se vuelve síncrona y la importación del grupo no finalizará hasta que finalice la destrucción. ¡Cuidado si necesitas reiniciar!
un CVn
Tengo un cliente con una freenas que perdió la conexión SMB en borrados grandes. Después de habilitar las instantáneas periódicas (y la eliminación automática), el problema "desapareció". la liberación del espacio lleva más tiempo en segundo plano, pero SMB-Share permanece accesible todo el tiempo.
Martin Seitl
6

Lo que estás pidiendo es imposible. O, más precisamente, hay un costo que pagar al eliminar un directorio y sus archivos; Si no lo paga en el momento de la eliminación, tendrá que pagarlo en otro lugar.

No solo está eliminando un directorio, eso sería casi instantáneo. Está eliminando un directorio y todos los archivos dentro de él y también eliminando de forma recursiva todos sus subdirectorios. Eliminar un archivo significa disminuir su recuento de enlaces y luego marcar sus recursos (los bloques se usan para el contenido y los metadatos del archivo, y el inodo si el sistema de archivos usa una tabla de inodo) como libre si el recuento de enlaces llega a 0 y el archivo no está abierto. Esta es una operación que debe realizarse para cada archivo en el árbol de directorios, por lo que el tiempo que toma es al menos proporcional al número de archivos.

Podría retrasar el costo de marcar los recursos como gratuitos. Por ejemplo, hay sistemas de archivos recolectados de basura, donde puede eliminar un directorio sin eliminar los archivos que contiene. Una ejecución del recolector de basura detectará los archivos a los que no se puede acceder a través de la estructura del directorio y los marcará como libres. Hacer rm -f directory; garbage-collecten un sistema de archivos recolectado basura hace lo mismo querm -rfen un sistema de archivos tradicional, con diferentes desencadenantes. Hay pocos sistemas de archivos recolectados de basura porque el GC es una complejidad adicional que rara vez se necesita. El tiempo de GC puede llegar en cualquier momento, cuando el sistema de archivos necesita algunos bloques libres y no encuentra ninguno, por lo que el rendimiento de una operación dependerá del historial pasado, no solo de la operación, que generalmente no es deseable. Tendría que ejecutar el recolector de basura solo para obtener la cantidad real de espacio libre.

Si desea simular el comportamiento de GC en un sistema de archivos normal, puede hacerlo:

mv directory .DELETING; rm -rf .DELETING &

(Omití muchos detalles importantes, como la verificación de errores, la resistencia a la pérdida de energía, etc.) El nombre del directorio se vuelve inexistente de inmediato; El espacio se recupera progresivamente.

Un enfoque diferente para evitar pagar el costo durante la eliminación sin GC sería pagarlo durante la asignación. Marque el árbol de directorios como eliminado y vaya a través de directorios eliminados al asignar bloques. Eso sería difícil de conciliar con enlaces duros, pero en un sistema de archivos sin enlaces duros, se puede hacer con un aumento de costos de O (1) en la asignación. Sin embargo, eso haría que una operación muy común (crear o ampliar un archivo) sea más costosa, con el único beneficio de ser una operación relativamente rara (eliminar un gran árbol de directorios) más barata.

Puede eliminar en masa un árbol de directorios si ese árbol se almacenó como su propio grupo de bloques. (Nota: estoy usando la palabra "grupo" en un significado diferente del "grupo de almacenamiento" de ZFS. No sé cuál es la terminología adecuada.) Eso podría ser muy rápido. ¿Pero qué haces con el espacio libre? Si lo reasigna a otro grupo, eso tiene un costo, aunque mucho menos que eliminar archivos individualmente. Si deja el espacio como espacio de reserva no utilizado, no puede reclamarlo de inmediato. Tener un grupo individual para un árbol de directorios significa costos adicionales para aumentar o reducir el tamaño de ese grupo (ya sea sobre la marcha o explícitamente). Hacer que el árbol sea su propio grupo de almacenamiento también aumenta el costo de mover archivos dentro y fuera del árbol.

Gilles 'SO- deja de ser malvado'
fuente
Ok, gran respuesta! La primera mitad de la cual es completamente satisfactoria en un sistema normal. ZFS tiene algunos trucos bajo la manga, por ejemplo, no hay necesidad de formatearlo, así que si destruyo el grupo, lo que creo que haré la próxima vez es simplemente hacer el grupo (plural) como se supone que debo hacer, entonces desaparece. el radar al instante, y ese espacio está disponible de inmediato. Supongo que estoy tratando de recrear eso en el zfs, en un directorio dentro de un grupo, y creo que como no es un grupo en sí mismo, la naturaleza se vuelve más estándar, y el método que mencionó parece aplicarse en ese caso. interesante.
Brian Thomas
Creo que ahí es donde cometí mi error, leí un artículo anoche, veré si puedo encontrarlo, que demuestre que las piscinas deben usarse como directorios limitados a ~ 18,446,744 billones de piscinas como máximo en el FS. si hago mis directorios de copia de seguridad superiores como grupos cada uno, cuando la copia de seguridad vaya a escribir en ellos, el directorio ya estará intacto, que es un grupo fácilmente eliminable. Si el grupo no existía, la copia de seguridad solo creará el directorio, y la piscina no se verá en el zfs list. Hasta entonces, con la esperanza de que alguien más tenga alguna información sobre cómo eliminar en masa ZFS en un subdirectorio de un grupo. :-)
Brian Thomas
Además, al leer su primera respuesta, mi primer pensamiento fue; "DERECHO", "el costo"! A eso me refería cuando hablaba de eliminar entradas de diario. así como sospechaba ¡maldito! Sin embargo, estás en el camino correcto. Vamos a inventar algo aquí, para que podamos armar un guión que haga esto quizás ... un pensamiento :-)
Brian Thomas
Brian, ten cuidado de no confundir zpools y conjuntos de datos. Si bien no existe un límite codificado en el número de zpools que pueda crear, estará rápidamente limitado por la cantidad de dispositivos subyacentes (por ejemplo, particiones) disponibles en su máquina. Además, tener grupos dedicados a directorios únicos derrotará algunas características valiosas de zfs y hará que las operaciones de movimiento sean mucho más lentas.
jlliagre
en este comentario que hizo aquí @Gilles "¿Pero qué hace con el espacio libre? Si lo reasigna a otro grupo, eso tiene un costo, aunque mucho menos que eliminar archivos individualmente", no estoy seguro, pero no creo que haya es una penalización crear un nuevo grupo, creo que lo trato solo durante el tiempo de escritura. nunca necesita ser particionado por la misma razón ... creo que este es el mismo mecanismo ...
Brian Thomas
1

Si tiene que ser rápido, genero un nuevo directorio temporal, mvel directorio debajo de él y luego borro recursivamente el temporal:

t=`mktemp -d`
mv certainFolder $t/
rm -rf $t &
Simon Richter
fuente
¿El & remove maneja o aplasta los errores?
Brian Thomas
1
Esto no es realmente diferente de la sugerencia de Gilles y tiene el mismo defecto. Si se reinicia el sistema operativo o el rmcomando no se completa por algún otro motivo, el directorio fantasma se deja sin recuperar.
jlliagre
ahh cierto, pero el & es nuevo para mí, eso es parte del rompecabezas ... quería deshacerme del mango. sin embargo, sí, tienes razón, no quieres esa basura si hay un problema ..
Brian Thomas
@BrianThomas &simplemente pone en segundo plano el proceso, para que pueda seguir haciendo otras cosas en el mismo shell mientras se ejecuta la eliminación (sujeto a cualquier penalización de rendimiento relevante).
un CVn