Journal fdupes : un utilitaire pour gagner de la place sur son disque dur

Posté par  . Licence CC By‑SA.
Étiquettes :
24
10
mai
2018

Un petit journal juste pour vous indiquer un petit utilitaire bien pratique nommé fdupes, qui permet de détecter les fichiers dupliqués sur votre machine.

J'ai découvert ce soft dans le cadre du nettoyage de données que je suis en train de faire sur mes disques durs.

En effet, il m'est souvent arrivé de copier des fichiers d'un répertoire à un autre pour réorganiser mes données sur mon (ou mes) disques, mais comme je n'aime pas jeter ni supprimer, j'ai accumulé certains fichiers en double ou en triple.

fdupes permet de parcourir les répertoires qu'on lui passe en paramètre et de faire un rapport sur les fichiers en doublon que l'on peut y trouver.

Pour identifier les doublons, fdupes effectue une comparaison de taille et de signature MD5 de chaque fichier, et ensuite une comparaison octet par octet est effectuée.

Cet utilitaire m'a permis de gagner près d'une centaine de gigas en 30 mn. Ya encore d u potentiel de gain de place, mais je préfère ne pas me précipiter, pour ne pas perdre malencontreusement des données (les 100 Gb gagnés me permettront de remettre en marche le processus de sauvegarde de mon portable, en attendant de mettre en place une solution à base de nas).

Note : pour supprimer mes fichiers dupliqués, je n'ai pas fait de rm sauvage: je les ai déplacés vers un dossier avant de les supprimer définitivement, pour éviter les grossières erreurs. Mon dernier rm -fr sur ~ m'a servi de leçon.

Un lien vers le dépot github du projet et un autre vers quelques explications d'utilisation en français.

  • # pas mal

    Posté par  . Évalué à 1.

    Pas mal. Tu as déjà testé avec un nextcloud/owncloud pour voir le résultat? :) (plus particulièrement si deux users ont un fichier identique, qu'on passe avec fdupe puis qu'un des users modifie ou supprime le fichier de son côté ?)

    • [^] # Re: pas mal

      Posté par  . Évalué à 6.

      Déjà fait. Ma compagne et moi avons des photos en commun mais avec chacun notre arborescence sur owncloud. Fdupes et hard links => gain de 40 GB. Owncloud fait des unlinks avant de réécrire un fichier donc pas de risque.

      • [^] # Re: pas mal

        Posté par  . Évalué à 0.

        D'ac merci. Tu sais si c'est risqué sur une partoche utilisée conjointement par nextcloud et par syncthing?

  • # doc ?

    Posté par  . Évalué à 4. Dernière modification le 10 mai 2018 à 14:59.

    la ligne de commande est documentée mais je n'ai pas trouvé d'informations sur l'algo de détection des doublons, je suppose qu'il faut savoir lire le C pour avoir les réponses aux questions que je me pose :

    • les signatures MD5 sont-elles stockées en mémoire ou bien sur disque dur ?

    • la comparaison octet par octet est-elle réalisée uniquement entre les fichiers ayant le même MD5 complet (pour éviter d'effacer des fichiers qui auraient la même signature mais pas le même contenu) ?

    j'en profite pour signaler l'existence d'autres outils du même genre :

    • rmlint, donné pour beaucoup plus rapide (quels risques de faux positifs ?)

    • ddupes, qui travailles sur les répertoires (et inclut fast fdupes)

    Envoyé depuis mon Archlinux

  • # fdupesfs ?

    Posté par  . Évalué à 3.

    Pour identifier les doublons, fdupes effectue une comparaison de taille et de signature MD5 de chaque fichier, et ensuite une comparaison octet par octet est effectuée.

    C'est effectivement un cas de figure qui revient fréquemment sur le devant de la scène, UNIX propose d'ailleurs des liens durs pratiquement depuis le début (surtout à une époque où l'espace disque coûtait cher). Et il m'arrive régulièrement de faire ce genre de stats.

    Du coup, il me vient idée à l'esprit : puisque les comparaisons de fichiers et le contrôle de leur somme (notamment avec Git), qui implique de les lire linéairement en une fois mais en entier, sont des choses récurrentes, serait-il envisageable d'intégrer cette fonctionnalité directement au système de fichier ? Et si oui, existe-t-il déjà des FS qui le fassent ?

    Le stockage sur disque implique déjà l'usage de CRC à très bas niveau (hardware et juste au dessus). Étant donné que les fonction de hachage comme MD5, SHA1, etc. sont de taille fixe et sont faites pour être faciles à calculer, c'est quelque chose que l'on pourrait envisager d'intégrer dans les inodes et que l'on récupérerait ensuite avec stat().

    • [^] # Re: fdupesfs ?

      Posté par  . Évalué à 2.

      Il y a bien "btrfs dedupe" mais cela reste un patch expérimental dont je ne sais s'il est encore vivant (derniers commits pour le kernel 4.12)

      https://btrfs.wiki.kernel.org/index.php/User_notes_on_dedupe

    • [^] # Re: fdupesfs ?

      Posté par  . Évalué à 3.

      Le stockage sur disque implique déjà l'usage de CRC à très bas niveau (hardware et juste au dessus). Étant donné que les fonction de hachage comme MD5, SHA1, etc. sont de taille fixe et sont faites pour être faciles à calculer, c'est quelque chose que l'on pourrait envisager d'intégrer dans les inodes et que l'on récupérerait ensuite avec stat().

      Tu peux mettre ça dans les xattr.

      Mais les fs qui font ça vont plus loin. Ils prennent pas en compte le fichier mais les chucks de fichiers et ils font du COW pour que si tu modifie le chuck, il l'écrit dans un nouvel espace et pointe vers ce nouvel espace. Tu n'a donc pas le soucis que tu as en utilisant des hards links.

      • [^] # Re: fdupesfs ?

        Posté par  . Évalué à 0.

        Pourrais-tu détailler stp?
        On peut paramétrer btrfs pour éviter les doublons auto ? Est-ce stable ?

  • # jdupes

    Posté par  . Évalué à 5. Dernière modification le 10 mai 2018 à 17:28.

    jdupes est un fork de fdupes, beaucoup plus rapide (entre autres)

    # time jdupes -m -r  /opt
    Scanning: 108436 files, 1513 items (in 1 specified)
    6411 duplicate files (in 5849 sets), occupying 398 MB       
    
    real    0m2,370s
    user    0m0,837s
    sys 0m1,506s
    
    # time fdupes -m -r  /opt
    6472 duplicate files (in 5850 sets), occupying 398.1 megabytes
    
    
    real    0m18,228s
    user    0m4,213s
    sys 0m13,929s

    On peut demander à {f,j}dupes de récupérer de la place en transformant les doublons en hardlinks (à manier avec les précautions d'usage).

    Ou bien sur un système de fichier BTRFS jdupes peut demander au kernel de dé-dupliquer les extents des fichiers doublons. En fait pour cela je préfère utiliser duperemove en lui passant éventuellement à traiter la sortie de jdupes.

    https://btrfs.wiki.kernel.org/index.php/Deduplication

    • [^] # Re: jdupes

      Posté par  . Évalué à 3.

      Au moins l'un des 2 logiciel est mauvais car ils ne trouvent pas le même nombre de fichiers dupliqués.

      • [^] # Re: jdupes

        Posté par  . Évalué à 2.

        Si tu veux :-) Les deux logiciels ne comptent peut-être pas de la même manière ou ont des options par défaut différentes sur les fichiers à considérer (taille, attributs, …)

        En l'occurrence "fdupes" comptabilise les fichiers vides ce que ne fait pas "jdupes"

        • [^] # Re: jdupes

          Posté par  . Évalué à 3.

          "fdupes" comptabilise les fichiers vides

          Il peut ne pas le faire avec l'option -n .
          man :
          -n --noempty
          exclude zero-length files from consideration

  • # plusieurs outils de dédoublonnage

    Posté par  . Évalué à 9. Dernière modification le 10 mai 2018 à 21:59.

    Il existe plusieurs outils de dédoublonnage en mode ligne de commande et qui ne soient pas forcément intégré au système de fichiers (comme l'est celui dans BTRFs) :
    fslint (findup), fdupes, jdupes, rdfind, duff, hadori, hardlink

    Certains sont des forks, réécritures ou amélioration d'un outil existant (jdupes par rapport fdupes)

    J'ai tenté il y a quelques mois de faire un mini-bench de ces outils (j'ai mis la version du paquet Debian à côté du nom du logiciel) :

    fdupes version 1.6.1-1+b1

    fdupes -rm /var/www/
    115221 duplicate files (in 21103 sets), occupying 4825.5 megabytes
    
    real    0m41,128s
    user    0m18,632s
    sys     0m22,264s

    rdfind version 1.3.4-2.1

    rdfind -n true /var/www/
    removed 71019 files from list.135099 files left.
    (DRYRUN MODE) It seems like you have 135099 files that are not unique
    (DRYRUN MODE) Totally, 4 Gib can be reduced.
    
    real    0m25,722s
    user    0m21,384s
    sys     0m4,316s

    duff version 0.5.2-1.1+b2

    duff -ar /var/www/ > /dev/null
    ... (pas de mode summary / trop de lignes)
    
    real    0m32,140s
    user    0m28,696s
    sys     0m3,408s

    jdupes version 1.7-2

    jdupes -rm /var/www/
    116284 duplicate files (in 21102 sets), occupying 5033 MB
    
    real    0m9,985s
    user    0m4,616s
    sys     0m5,292s

    hadori version 1.0-1

    hadori -tn /var/www/
    
    (beaucoup trop long...arrêt du programme !)

    hardlink version 0.3.0+b1

    hardlink -n /var/www/
    Mode:     dry-run
    Files:    327890
    Linked:   36010 files
    Compared: 0 xattrs
    Compared: 333440 files
    Saved:    1,22 GiB
    Duration: 3,55 seconds
    
    real    0m3,520s
    user    0m1,140s
    sys     0m2,368s

    Le test portait sur le répertoire /var/www qui contenait 327890 fichiers, 2144 liens symboliques et 50712 répertoires (et quelques répertoires/fichiers inaccessibles pour agrémenter le tout), mais qui avait aussi déjà 46235 fichiers hardlinkés (lien dur).

    On se rends compte que c'est hardlink qui est le plus rapide (3,5 secondes), mais qu'il trouve bien moins de fichiers identiques que jdupes qui met à peine plus de 6 secondes supplémentaires pour trouver 116284 fichiers en double parmi 21102 groupes (c'était probablement dû aux 46k fichiers déjà liés (hard link via ln), mais ça n'empêche que le compte n'y est pas.

    Je n'ai malheureusement pas creuser ce test et je continue d'utiliser hardlink ou jdupes selon les cas (par ex. pour éliminer les sauvegardes PostgreSQL redondantes).

    n.b. : la commande findup du paquet fslint n'a pas été testée (/usr/share/fslint/fslint/findup)

    Il est intéressant de noter que seul jdupes propose une option (-B / --dedupe) permettant d'envoyer un ioctl "same-extents" pour indiquer au système de fichier Btrfs de déclencher une déduplication au niveau FS (lorsque l'outil a été compilé avec le support idoine).

    • [^] # Re: plusieurs outils de dédoublonnage

      Posté par  . Évalué à 2.

      rmlint fonctionne mieux que jdupes pour Btrfs je trouve.

    • [^] # Re: plusieurs outils de dédoublonnage

      Posté par  . Évalué à 1.

      Hardlink (ou hardlinkpy) c’est effectivement pas mal (notamment quand on utilise pas brtfs) ! Je l’utilise depuis un bail (j’ai même participé à la vague de forks sur github quand Google code a fermé). Après moult tests, je n’avais pas trouvé mieux, pas qu’en termes de performance, en termes de flexibilité et de fiabilité aussi.

      Il faut que j’essaie jdupes pour voir s’il trouve effectivement de nouveaux dupes.

    • [^] # Re: plusieurs outils de dédoublonnage

      Posté par  . Évalué à 5. Dernière modification le 13 mai 2018 à 15:33.

      Il existe de nombreux outils de dédoublonnage. A commencer par fslint (dont la sous-commande findup est marrante à lire car c'est en fait un gros pipe). La plupart d'entre eux fonctionne sur le même principe

      • parcourir le filesystem et identifier les fichiers de même taille
      • sur ces derniers, calculer un hash (md5 ou autre, éventuellement en le faisant par inode croissant pour éviter que les vieux disques durs ne battent les blancs en neige - beaucoup moins utile avec les SSD d'aujourd'hui. N.B. J'ai récemment découvert xxhash qui est bien plus rapide qu'un MD5 et même apparemment aussi bien plus rapide qu'un CRC. N.B. d'après mon expérience faire un hash sur le début/fin/milieu de fichier est souvent suffisant (pas la peine de parcourir l'entièreté des gros fichiers .iso par exemple… et c'est exactement ce que fait imohash. Evidemment c'est plus risqué dans le cas d'une VM et ça ne dispense pas de checks additionnels)
      • si deux fichiers ont à la fois même taille et même hash (parfois avec un double-check e.g. SHA1 en plus du CRC ou MD5), ils sont considérés comme identiques (souvent indépendamment de leur nom)

      De mon côté, je ne souhaite pas qu'un outil fasse des modifications sur mon fs, mais juste qu'il m'indique quels sont les fichiers/dossiers en double pour m'aider à faire le tri. Sauf que… tous les outils que je connais (y compris fslint) me listent toute les sous-arborescences en double au lieu de factoriser la réponse avec juste "ces deux dossiers sont identiques". C'est pour ça que j'ai écrit Duplicide il y a longtemps. Ce n'est sûrement pas le plus rapide (je pense à le réécrire en Go avec imohash + xxhash car à l'heure actuelle avec mon SSD je suis CPU-bound, mais comme mon implémentation actuelle en Python utilise déjà une approche analogue à imohash ça me renvoie quand même un résultat en un temps raisonnable) et ce n'est sûrement pas parfait (feedback welcome :), et comme c'est sûrement encore buggé ça ne dispense pas d'un double check pour vérifier qu'il ne renvoie pas de faux positif (l'outil n'est pas sensé modifier vos données, mais j'ai mis le disclaimer habituel i.e. je ne suis pas responsable en cas de pépin et vous utilisez l'outil à vos propres risques, etc.), mais à mon niveau ça m'a bien aidé à faire le tri et réorganiser mes données alors que j'avais plusieurs backups non synchronisés sur plusieurs supports différents.

  • # GOTCHA / CAVEAT

    Posté par  . Évalué à 3.

    le seul risque que l'on peut avoir lorsque l'on dédoublonne des fichiers en les "liant" entre eux (hardlink), c'est qu'en changeant l'un d'eux, ça change tous ceux qui sont pointés par le même inode

    la solution c'est d'effectuer une copie du fichier avant de l'éditer

    il existe une option dans à mettre dans le vimrc pour déclencher la copie automatiquement lors de l'édition :
    set bkc=no

  • # hardlink → comment défaire ?

    Posté par  (site web personnel) . Évalué à 1.

    Il y a quelques mois, je posais la question de savoir comment délier les fichiers lié avec hardlink :

    https://linuxfr.org/forums/linux-general/posts/hardlink-comment-defaire

    Je n'ai pas eu de réponse simple et efficace pour tout une branche (dossier et sous-dossier, de manière récursive, et sans avoir besoin de tout copier) :(

    Si vous avez une solution… ?

    Le truc, c'est que j'ai mis au point trop tard le jeu d'options pour ne considérer par exemple que les fichiers de plus de 1 Mo (et donc pas les plus petits). Ainsi, je n'obtient de liens que pour les photos JPEG, mais pas pour les petit fichiers textes autour…

    hardlink -s 1M leDossier

    L'option -i devrait permettre de ne considérer que les fichiers avec tel ou tel extension…

    Bref, j'aimerais pouvoir défaire tout les liens durs des fichiers, soit tout et relancer ensuite avec l'option, soit défaire dès lors que le fichier serait plus petit que 1 Mo.

    Qu'en pensez-vous ?

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.