Supprimer en bloc un grand répertoire sur un ZFS sans le parcourir récursivement

9

Je souhaite supprimer un répertoire contenant de grandes quantités de données. Il s'agit de ma baie de sauvegarde, qui est un système de fichiers ZFS , une étendue linéaire, un pool unique appelé "san". San est monté sur /san donc je veux supprimer en bloc / san / thispc / certainFolder

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

Plutôt que de devoir attendre, rm -rf certainFolder/je ne peux pas simplement détruire le descripteur de ce répertoire pour qu'il soit écrasable (même par le même nom de répertoire si je choisis de le recréer) ??

Par exemple, pour ne pas savoir grand-chose sur la gestion interne de zfs fs, spécifiquement sur la façon dont il mappe les répertoires, mais si je trouve cette carte, par exemple, et que je supprime les bonnes entrées pour, par exemple, le répertoire ne s'affichera plus, et cet espace que le répertoire contenait auparavant. doit également être retiré d'une sorte d'audit.

Existe-t-il un moyen facile de le faire, même sur un ext3 fs, ou est-ce déjà ce que la commande de suppression récursive doit faire en premier lieu, à savoir piloter et éditer des journaux?

J'espère juste faire quelque chose du genre kill thisDiroù il supprime simplement une sorte d'ID, et poof le répertoire n'apparaît plus ls -laet les données sont toujours là sur le lecteur, bien sûr, mais l'espace sera maintenant réutilisé ( écrasé), parce que ZFS est juste cool?

Je veux dire, je pense que zfs est vraiment cool, comment pouvons-nous le faire? Idéalement? se frotter les mains :-)

Mon cas d'utilisation spécifique (outre mon amour pour zfs) est la gestion de mes archives de sauvegarde. Ce répertoire de sauvegarde est poussé vers via freefilesync (AWESOME PROG) sur ma boîte Windows vers un partage de fichiers smb, mais a également un répertoire de version où les anciens fichiers vont. Je supprime les répertoires de niveau supérieur qui résident dans la sauvegarde principale, qui ont été copiés dans la version - par exemple /san/version/someStuff, comme un nettoyage bimensuel d' rm -rf /san/version/someStuff/*un terminal de mastic, maintenant je dois ouvrir un autre terminal; Je ne veux pas faire ça à chaque fois, je suis fatigué de devoir inutilement surveiller rm -rf.

Je veux dire, je devrais peut-être définir la commande pour simplement relâcher la poignée, puis imprimer sur std out, cela pourrait être bien. Plus réaliste , recréez l'ensemble de données en quelques secondes zfs destroy san/version; zfs create -p -o compression=on san/versionaprès les réflexions de la réponse de @Gilles.

Brian Thomas
la source
Pour info, j'ai exécuté cette commande pour créer les jeux de données que j'utilise actuellement .. `zfs create dataset -p -o compression=on yourPoolName/BackupRootDir/hostNameYourPc/somesubdir
Brian Thomas
Veuillez accepter une réponse si l'on a résolu le problème décrit dans votre question d'origine. Le problème que vous venez d'ajouter à votre question semble très différent et devrait donc vraiment être posé dans une nouvelle question.
jlliagre

Réponses:

12

Le suivi des blocs libérés est inévitable dans tout système de fichiers décent et ZFS ne fait pas exception . Il existe cependant un moyen simple sous ZFS d'avoir une suppression de répertoire presque instantanée en "différant" le nettoyage sous-jacent. Elle est techniquement très similaire à la suggestion de Gilles mais est intrinsèquement fiable sans nécessiter de code supplémentaire.

Si vous créez un instantané de votre système de fichiers avant de supprimer le répertoire, la suppression du répertoire sera très rapide car rien ne devra être exploré / libéré en dessous, tous étant toujours référencés par l'instantané. Vous pouvez ensuite détruire l'instantané en arrière-plan afin que l'espace soit progressivement récupéré.

d=yourPoolName/BackupRootDir/hostNameYourPc/somesubdir
zfs snapshot ${d}@quickdelete && { 
    rm -rf /${d}/certainFolder
    zfs destroy ${d}@quickdelete & 
}
jlliagre
la source
ok, je ne connaissais pas les instantanés. cela pourrait m'aider. j'ai toujours supprimé / déplacé toute la journée. J'ai créé des ensembles de données non seulement pour le répertoire de sauvegarde principal, mais aussi pour les répertoires de niveau supérieur, chacun commençant par le nom d'hôte et quelques niveaux supérieurs .., j'ai donc un peu de flexibilité pour détruire et recréer un pool, mais ce n'est pas parfait , parce que je ne veux pas toujours supprimer tous ces répertoires de pool, je devrais en créer encore plus, et c'est beaucoup de création de jeux de données, donc j'aime votre suggestion pour cette raison!
Brian Thomas
4
Si disponible, feature@async_destroypeut également aider à accélérer cela (du point de vue d'un utilisateur ou d'un administrateur) s'il est activé; voir zpool get all $pool. Notez qu'au moins j'ai regardé, s'il y a une destruction en cours en cours lors de l'importation du pool , alors cette destruction devient synchrone et l'importation du pool ne se terminera pas avant la fin de la destruction. Attention si vous devez redémarrer!
un CVn du
J'ai un client avec un freenas qui a perdu la connexion SMB lors de suppressions importantes. Après avoir activé les instantanés périodiques (et la suppression automatique), le problème a "disparu". la libération de l'espace prend plus de temps en arrière-plan, mais le SMB-Share reste accessible tout le temps.
Martin Seitl
6

Ce que vous demandez est impossible. Ou, plus précisément, il y a un coût à payer lors de la suppression d'un répertoire et de ses fichiers; si vous ne le payez pas au moment de la suppression, vous devrez le payer ailleurs.

Vous ne supprimez pas seulement un répertoire - ce serait presque instantané. Vous supprimez un répertoire et tous les fichiers qu'il contient et supprimez également de manière récursive tous ses sous-répertoires. Supprimer un fichier signifie décrémenter son nombre de liens, puis marquer ses ressources (les blocs utilisent pour le contenu du fichier et les métadonnées de fichier, et l'inode si le système de fichiers utilise une table d'inode) comme libre si le nombre de liens atteint 0 et que le fichier n'est pas ouvert. Il s'agit d'une opération qui doit être effectuée pour chaque fichier dans l'arborescence de répertoires, donc le temps qu'il faut est au moins proportionnel au nombre de fichiers.

Vous pourriez retarder le coût du marquage des ressources comme gratuites. Par exemple, il existe des systèmes de fichiers à récupération de place, où vous pouvez supprimer un répertoire sans supprimer les fichiers qu'il contient. Une exécution du garbage collector détectera les fichiers qui ne sont pas accessibles via la structure de répertoires et les marquera comme libres. Faire rm -f directory; garbage-collectsur un système de fichiers récupéré fait la même chose querm -rfsur un système de fichiers traditionnel, avec différents déclencheurs. Il y a peu de systèmes de fichiers récupérés car le GC est une complexité supplémentaire qui est rarement nécessaire. L'heure du GC peut arriver à tout moment, lorsque le système de fichiers a besoin de blocs libres et n'en trouve aucun, de sorte que les performances d'une opération dépendent de l'historique, et pas seulement de l'opération, ce qui est généralement indésirable. Vous auriez besoin d'exécuter le garbage collector juste pour obtenir la quantité réelle d'espace libre.

Si vous souhaitez simuler le comportement du GC sur un système de fichiers normal, vous pouvez le faire:

mv directory .DELETING; rm -rf .DELETING &

(J'ai omis de nombreux détails importants tels que la vérification des erreurs, la résilience aux coupures de courant, etc.) Le nom du répertoire devient immédiatement inexistant; l'espace est progressivement récupéré.

Une approche différente pour éviter de payer le coût lors de l'enlèvement sans GC serait de le payer lors de l'allocation. Marquez l'arborescence des répertoires comme supprimée et parcourez les répertoires supprimés lors de l'allocation des blocs. Ce serait difficile à concilier avec des liens durs, mais sur un système de fichiers sans liens durs, cela peut être fait avec une augmentation de coût O (1) dans l'allocation. Cependant, cela rendrait une opération très courante (création ou agrandissement d'un fichier) plus coûteuse, avec pour seul avantage une opération relativement rare (suppression d'une grande arborescence de répertoires) moins coûteuse.

Vous pouvez supprimer en bloc une arborescence de répertoires si cette arborescence était stockée comme son propre pool de blocs. (Remarque: j'utilise le mot «pool» dans un sens différent de «pool de stockage» de ZFS. Je ne connais pas la terminologie appropriée.) Cela pourrait être très rapide. Mais que faites-vous de l'espace libre? Si vous le réaffectez à un autre pool, cela a un coût, bien que beaucoup moins que la suppression de fichiers individuellement. Si vous laissez l'espace comme espace de réserve inutilisé, vous ne pouvez pas le récupérer immédiatement. Avoir un pool individuel pour une arborescence de répertoires signifie des coûts supplémentaires pour augmenter ou réduire la taille de ce pool (à la volée ou explicitement). Faire de l'arborescence son propre pool de stockage augmente également le coût de déplacement des fichiers dans et hors de l'arborescence.

Gilles 'SO- arrête d'être méchant'
la source
Ok bonne réponse! Dont la première moitié est entièrement satisfaisable sur un système normal. ZFS a quelques astuces dans sa manche, par exemple, il n'est pas nécessaire de le formater, donc si je détruis le pool, ce que je pense que je vais faire la prochaine fois, c'est simplement faire le pool (pluriel) comme im supposé, puis ti disparaît le radar instantanément, et cet espace est immédiatement disponible. Je suppose que j'essaie de recréer cela sur le zfs, sur un répertoire à l'intérieur d'un pool, et je pense que puisque ce n'est pas un pool lui-même, la nature de celui-ci devient plus standard, et la méthode que vous avez mentionnée semble s'appliquer dans ce cas. intéressant.
Brian Thomas
Je pense que c'est là que j'ai fait mon erreur, j'ai lu un article hier soir, je vais voir si je peux le trouver, qui démontre que les pools doivent être utilisés comme des répertoires limités à ~ 18 446 744 trillions de pools max sur le FS. si je crée mes répertoires de sauvegarde supérieurs sous forme de pools chacun, lorsque la sauvegarde va y écrire, le répertoire sera déjà en contact, ce qui est un pool facilement supprimable. Si le pool n'existait pas, la sauvegarde créera simplement le répertoire, et la piscine ne sera pas vue dans le zfs list. Jusque-là, en espérant que quelqu'un d'autre ait une entrée sur la façon de supprimer en bloc ZFS dans un sous-répertoire d'un pool. :-)
Brian Thomas
Aussi, en lisant votre première réponse, ma première pensée a été; "DROIT!", "Le coût"! c'est ce que je touchais lorsque je parlais de supprimer des entrées de journal. donc comme je le soupçonnais. Zut! Cependant, vous êtes sur la bonne voie. Permet de trouver quelque chose ici, afin que nous puissions obtenir un script qui le fera peut-être ... une pensée :-)
Brian Thomas
Brian, méfiez-vous de ne pas confondre les zpools et les jeux de données. Bien qu'il n'y ait en effet aucune limite codée en dur accessible sur le nombre de zpools que vous pouvez créer, vous serez rapidement limité par le nombre de périphériques sous-jacents (par exemple les partitions) disponibles sur votre machine. De plus, le fait d'avoir des pools dédiés à des répertoires uniques annihilera certaines fonctionnalités zfs précieuses et rendra les opérations de déplacement beaucoup plus lentes.
jlliagre
sur ce commentaire que vous avez fait ici @ Gilles "Mais que faites-vous avec l'espace libre? Si vous le réaffectez à un autre pool, cela a un coût, bien que beaucoup moins que de supprimer des fichiers individuellement" je ne suis pas sûr, mais je ne pense pas qu'il y est un pénalisateur qui crée un nouveau pool, je pense que je m'en occupe uniquement pendant le temps d'écriture. n'a jamais besoin d'être partitionné pour la même raison .. je crois que c'est le même mécanisme ..
Brian Thomas
1

Si cela doit être rapide, je génère un nouveau répertoire temporaire, mvle répertoire en dessous, puis supprime récursivement le temporaire:

t=`mktemp -d`
mv certainFolder $t/
rm -rf $t &
Simon Richter
la source
la poignée & remove, ou les erreurs de squash?
Brian Thomas
1
Ce n'est pas vraiment différent de la suggestion de Gilles et a le même défaut. Si le système d'exploitation est redémarré ou si la rmcommande ne s'exécute pas pour une autre raison, le répertoire fantôme n'est pas supprimé.
jlliagre
ahh c'est vrai, mais le & est nouveau pour moi, c'est une partie du puzzle ... je voulais me débarrasser du manche. mais oui, tu
Brian Thomas
@BrianThomas met &simplement en arrière-plan le processus, vous pouvez donc continuer à faire d'autres choses dans le même shell pendant la suppression (sous réserve des éventuelles pénalités de performances pertinentes).
un CVn le