Votre société de services en logiciels libres

Comment réduire la taille d’un répertoire ?

13 avril 2015   
Comment réduire la taille d’un répertoire ?

Tout Unixien sait bien que la taille d’un répertoire, obtenue par la commande « ls -lhd /chemin/vers/rep », ne donne pas la taille du contenu du répertoire, taille qu’on obtiendrait par la commande « du -sh /chemin/vers/repertoire ».

La « taille » d’un répertoire (au sens « ls -lhd ») est fonction du nombre de fichiers qu’il contient, que ces fichiers soient volumineux ou non. Ainsi, quand vous créez un répertoire, sa taille est initialement de 4 Ko, puis passe à 8, 16, 24 Ko…. si de nouveaux fichiers sont créés dans ce répertoire.

Certains répertoires peuvent contenir à un moment donnée, des centaines de milliers de fichiers, et dans ce cas, la taille nécessaire au stockage du répertoire va croitre pour atteindre des dizaines, voire des centaines de Mo. Ce cas arrive typiquement avec des répertoires qui stockent de mails « à plat », ou bien suite à une erreur de rotation de logs, etc…

Une fois que vous avez supprimés les fichiers indésirables, vous constaterez que la taille du répertoire n’est pas diminuée pour autant ! Cela est du à une réelle difficulté d’implémentation pour les systèmes de fichiers de type ext/2/3/4.

Une solution élégante consiste à utiliser la commande rsync avec l’option –link-dest, qui peut aussi être utilisée pour réaliser des backups incrémentaux.

La commande suivante « rsync –link-dest=REP SOURCE DEST » a le fonctionnement suivant :

si le répertoire REP existe, rsync compare les fichiers de SOURCE à ceux de REP. Les fichiers identiques de REP deviennent des « hard-links » sous DEST, les autres sont recopiés sous DEST.

Ainsi, il est possible de récupérer l’espace pris pour la structure d’un répertoire SOURCE, en exécutant les commandes suivantes :

# mkdir /chemin/vers/NOUVEAU
# rsync -ai --delete --link-dest=/chemin/vers/SOURCE \
                      /chemin/vers/SOURCE/ /chemin/vers/NOUVEAU/
# mv /chemin/vers/SOURCE/ /chemin/vers/SOURCE.SAUVE/
# mv /chemin/vers/NOUVEAU/ /chemin/vers/SOURCE/

Bien sûr, il faudra que les répertoires SOURCE et NOUVEAU soient sur le même système de fichiers…