Solution 1 :
Créez un script bash comme celui-ci :
#!/bin/bash
rm -- "$*"
sleep 0.5
Enregistrez-le avec le nom deleter.sh
par exemple. Exécutez chmod u+x deleter.sh
pour le rendre exécutable.
Ce script supprime tous les fichiers qui lui sont transmis en tant qu'arguments, puis dort 0,5 seconde.
Ensuite, vous pouvez exécuter
find cache.bak -print0 | xargs -0 -n 5 deleter.sh
Cette commande récupère une liste de tous les fichiers dans cache.bak et transmet les cinq noms de fichiers à la fois au script de suppression.
Ainsi, vous pouvez ajuster le nombre de fichiers supprimés à la fois et le délai entre chaque opération de suppression.
Solution 2 :
Vous devriez envisager de sauvegarder votre cache sur un système de fichiers séparé que vous pouvez monter/démonter comme quelqu'un l'a indiqué dans les commentaires. Jusqu'à ce que vous le fassiez, vous pouvez utiliser cette doublure /usr/bin/find /path/to/files/ -type f -print0 -exec sleep 0.2 \; -exec echo \; -delete
en supposant que votre binaire de recherche se trouve sous /usr/bin et que vous souhaitez voir la progression à l'écran. Ajustez le sommeil en conséquence, afin de ne pas trop solliciter votre disque dur.
Solution 3 :
Vous voudrez peut-être essayer ionice sur un script consommant la sortie d'une commande find. Quelque chose comme ce qui suit :
ionice -c3 $(
for file in find cache.bak -type f; do
rm $file
done
for dir in find cache.bak -depthe -type d -empty; do
rmdir $dir
done
)
Selon le système de fichiers, chaque suppression de fichier peut entraîner la réécriture de tout ce répertoire. Pour les grands répertoires, cela peut être un succès. Des mises à jour supplémentaires sont requises pour la table d'inodes, et éventuellement une liste d'espace libre.
Si le système de fichiers a un journal, les modifications sont écrites dans le journal; appliqué; et retiré du journal. Cela augmente les exigences d'E/S pour les activités d'écriture intensives.
Vous voudrez peut-être utiliser un système de fichiers sans journal pour le cache.
Au lieu d'ionice, vous pouvez utiliser une commande sleep pour limiter les actions. Cela fonctionnera même si ionice ne fonctionne pas, mais cela prendra beaucoup de temps pour supprimer tous vos fichiers.
Solution 4 :
J'ai reçu de nombreuses réponses / commentaires utiles ici, que j'aimerais conclure et montrer également ma solution.
-
Oui, la meilleure façon de prévenir une telle chose qui se passe est de garder le répertoire de cache sur un système de fichiers séparé. Le nuking/formatage rapide d'un système de fichiers prend toujours quelques secondes (peut-être quelques minutes) au maximum, sans rapport avec le nombre de fichiers/répertoires qui y étaient présents.
-
Le
ionice
/nice
les solutions n'ont rien fait, car le processus de suppression n'a en fait causé presque aucune E/S. Ce qui a causé les E/S, c'est que je crois que les files d'attente/tampons au niveau du noyau/du système de fichiers se remplissaient lorsque les fichiers étaient supprimés trop rapidement par le processus de suppression. -
La façon dont je l'ai résolu est similaire à la solution de Tero Kilkanen, mais ne nécessite pas l'appel d'un script shell. J'ai utilisé rsync intégré dans
--bwlimit
commutateur pour limiter la vitesse de suppression.
La commande complète était :
mkdir empty_dir
rsync -v -a --delete --bwlimit=1 empty_dir/ cache.bak/
Maintenant, bwlimit spécifie la bande passante en kilobyes, qui dans ce cas s'applique au nom de fichier ou au chemin des fichiers. En le réglant sur 1 KBps, il supprimait environ 100 000 fichiers par heure, soit 27 fichiers par seconde. Les fichiers avaient des chemins relatifs comme cache.bak/e/c1/db98339573acc5c76bdac4a601f9ec1e
, qui contient 47 caractères, donc cela donnerait 1000/47 ~=21 fichiers par seconde, donc un peu similaire à mon estimation de 100 000 fichiers par heure.
Maintenant pourquoi --bwlimit=1
? J'ai essayé différentes valeurs :
- 10000, 1000, 100 -> le système ralentit comme avant
- 10 -> le système fonctionne assez bien pendant un certain temps, mais produit des ralentissements partiels une fois par minute environ. Temps de réponse HTTP toujours <1 sec.
- 1 -> aucun ralentissement du système. Je ne suis pas pressé et 2 millions de fichiers peuvent être supprimés en <1 jour de cette façon, alors je le choisis.
J'aime la simplicité de la méthode intégrée de rsync, mais cette solution dépend de la longueur relative du chemin. Ce n'est pas un gros problème car la plupart des gens trouveraient la bonne valeur par essais et erreurs.