J'ai 200 Go d'espace disque libre, 16 Go de RAM (dont ~ 1 Go sont occupés par le bureau et le noyau) et 6 Go de swap.
J'ai un SSD externe de 240 Go, avec 70 Go utilisés 1 et le reste libre, que je dois sauvegarder sur mon disque.
Normalement, je voudrais dd if=/dev/sdb of=Desktop/disk.img
d'abord le disque, puis le compresser, mais créer l'image en premier n'est pas une option car cela nécessiterait beaucoup plus d'espace disque que moi, même si l'étape de compression entraînera l'écrasement de l'espace libre de sorte que le l'archive finale peut facilement tenir sur mon disque.
dd
écrit dans STDOUT par défaut, et gzip
peut lire depuis STDIN, donc en théorie je peux écrire dd if=/dev/sdb | gzip -9 -
, mais il gzip
faut beaucoup plus de temps pour lire les octets que ce qui dd
peut les produire.
De man pipe
:
Les données écrites à l'extrémité d'écriture du canal sont mises en mémoire tampon par le noyau jusqu'à ce qu'elles soient lues à l'extrémité de lecture du canal.
Je visualise un |
comme étant un vrai tube - une application insérant des données et l'autre retirant les données de la file d'attente du tube le plus rapidement possible.
Que se passe-t-il lorsque le programme sur le côté gauche écrit plus de données plus rapidement que l'autre côté du tuyau peut espérer les traiter? Cela entraînera-t-il une utilisation extrême de la mémoire ou des échanges, ou le noyau essaiera-t-il de créer une FIFO sur le disque, remplissant ainsi le disque? Ou échouera-t-il simplement SIGPIPE Broken pipe
si le tampon est trop volumineux?
Fondamentalement, cela se résume à deux questions:
- Quelles sont les implications et les résultats de l'introduction de plus de données dans un tube que ce qui est lu à la fois?
- Quel est le moyen fiable de compresser un flux de données sur le disque sans placer l'intégralité du flux de données non compressé sur le disque?
Remarque 1: je ne peux pas simplement copier exactement les 70 premiers Go utilisés et m'attendre à obtenir un système ou un système de fichiers fonctionnel, en raison de la fragmentation et d'autres choses qui nécessiteront l'intégralité du contenu.
la source
lzop
lieu degzip
; il se comprime beaucoup plus rapidement avec seulement un taux de compression légèrement inférieur. Je le trouve idéal pour les images de disque où la vitesse de compression peut être un véritable goulot d'étranglement.Réponses:
Techniquement, vous n'avez même pas besoin
dd
:Si vous utilisez
dd
, vous devriez toujours aller avec plus grand que blocksize par défaut commedd bs=1M
ou subir l'enfer syscall (dd
de » la blocksize par défaut est de 512 octets, car ilread()
s etwrite()
s qui est4096
syscalls parMiB
, trop frais généraux).gzip -9
utilise beaucoup plus de CPU avec très peu à montrer pour cela. Si celagzip
vous ralentit, abaissez le niveau de compression ou utilisez une méthode de compression différente (plus rapide).Si vous effectuez des sauvegardes basées sur des fichiers au lieu d'
dd
images, vous pouvez avoir une logique qui décide de compresser ou non (cela ne sert à rien pour différents types de fichiers).dar
(tar
alternative`) est un exemple qui a des options pour le faire.Si votre espace libre est ZÉRO (car c'est un SSD qui retourne zéro de manière fiable après TRIM et que vous avez exécuté
fstrim
et déposé des caches), vous pouvez également utiliserdd
avecconv=sparse
flag pour créer une image clairsemée montable en boucle non compressée qui utilise zéro espace disque pour les zones nulles . Nécessite que le fichier image soit sauvegardé par un système de fichiers qui prend en charge des fichiers clairsemés.Alternativement, pour certains systèmes de fichiers, il existe des programmes capables de n'imaginer que les zones utilisées.
la source
dd bs=1M
" - Vous pouvez, mais ne vous attendez pas à trop. Sur mon PC,dd
fera environ 2 Go / s avec des blocs de 512 octets. Ce ne sera pas le goulot d'étranglement;gzip
sera.dd
2 Go / s avec des blocs de 512 octets, je serais surpris s'il n'atteignait pas 100% du cœur du processeur dans le processus. Maintenant, si votre boîte est un quadcore qui reste inactif de toute façon, vous ne remarquerez peut-être pas de différence. Mais tout le monde le fait toujours.dd
taille de bloc est mentionnée, les gens viennent taquiner.gzip
être intensif en cpu faisait également partie de ma réponse, d'accord? Et désolé, je ne suis pas d'accord avec "négligeable". Il ne peut ajouter que 1 à 2 par concert avecgzip -9
(mais cela équivaut toujours à des minutes lors du traitement de centaines de concerts), mais en suivant vos conseils,lzop -1
c'est 1 par concert contre 4 par concert. Testé sur une pomme de terre (vserver monocœur). L'ajout d'une taille de bloc sainedd
ne coûte rien et n'a aucun inconvénient. Ne pique pas. Simplement fais-le. ymmvdd
lit et écrit des données un bloc à la fois, et il n'a qu'un seul bloc en attente. Alorsmontre qui
dd
utilise environ 1 Mo de mémoire. Vous pouvez jouer avec la taille du bloc et la laisser tombervalgrind
pour voir l'effet surdd
la vitesse de.Lorsque vous vous connectez
gzip
,dd
ralentit simplement pour correspondre àgzip
la vitesse. Son utilisation de la mémoire n'augmente pas et n'entraîne pas le stockage du tampon sur le disque par le noyau (le noyau ne sait pas comment faire, sauf via swap). Un tuyau cassé ne se produit que lorsque l'une des extrémités du tuyau meurt; voirsignal(7)
etwrite(2)
pour plus de détails.Ainsi
est un moyen sûr de faire ce que vous recherchez.
Lors du piping, le processus d'écriture finit par être bloqué par le noyau si le processus de lecture ne suit pas. Vous pouvez le voir en exécutant
Vous verrez que
dd
lit 1 Mo, puis émet unwrite()
qui reste là en attente pendant une minute pendant l'sleep
exécution. C'est ainsi que les deux côtés d'un tube s'équilibrent: le noyau bloque l'écriture si le processus d'écriture est trop rapide et il bloque la lecture si le processus de lecture est trop rapide.la source
dd
sait-on ralentir pour correspondre àgzip
la vitesse? Il est automatique, comme par le noyau, ou calcule-t-il à partir des métadonnées sur son descripteur de fichier de sortie?dd
appellewrite()
pour mettre des données dans le canal.write()
transfère en fait le contrôle au noyau afin qu'il puisse manipuler la mémoire du canal. Si le noyau voit que le tuyau est plein, il attendra ("bloquer") jusqu'à ce que le tuyau ait assez de place. Ce n'est qu'alors que l'write()
appel se terminera et transférera le contrôle versdd
, qui réécrira ensuite les données dans le canal.Il n'y a pas d'implications négatives autres que les performances: le canal a un tampon, qui est généralement de 64 Ko, et après cela, une écriture dans le canal se bloque simplement jusqu'à ce qu'il
gzip
lit plus de données.la source
Répondre à la question réelle de savoir comment cela fonctionne: "que se passe-t-il si le programme sur le côté gauche écrit plus de données plus rapidement que l'autre côté du tuyau peut espérer les traiter?"
Cela n'arrive pas. Il y a un tampon assez petit et de taille limitée dans le tuyau; voir Quelle est la taille du tampon de tuyau?
Une fois que le tampon de canal est plein, le programme émetteur se bloque . Lorsqu'il effectue un appel en écriture, le noyau ne rendra pas le contrôle au programme tant que les données n'auront pas été écrites dans le tampon. Cela donne au programme de lecture le temps CPU pour vider le tampon.
la source
Peut-être n'avez-vous besoin que des fichiers, puis utilisez tar. Vous pouvez remplir avec des zéros les blocs qui ne contiennent pas tout ce que vous voulez, quelqu'un a déjà posé une question à ce sujet. Effacez l'espace inutilisé avec des zéros (ext3, ext4)
Ensuite, il y a
pigz
ce qui est généralement plus rapide quegzip
.la source