Tengo 200 GB de espacio libre en disco, 16 GB de RAM (de los cuales ~ 1 GB está ocupado por el escritorio y el núcleo) y 6 GB de intercambio.
Tengo un SSD externo de 240 GB, con 70 GB utilizados 1 y el resto libre, que necesito hacer una copia de seguridad en mi disco.
Normalmente, dd if=/dev/sdb of=Desktop/disk.img
primero usaría el disco y luego lo comprimiría, pero hacer la imagen primero no es una opción, ya que hacerlo requeriría mucho más espacio en el disco que el que tengo, aunque el paso de compresión provocará que el espacio libre se aplaste, por lo que El archivo final puede caber fácilmente en mi disco.
dd
escribe en STDOUT de forma predeterminada y gzip
puede leer desde STDIN, por lo que, en teoría, puedo escribir dd if=/dev/sdb | gzip -9 -
, pero gzip
tarda mucho más en leer los bytes que dd
puede producirlos.
De man pipe
:
Los datos escritos en el extremo de escritura de la tubería se almacenan en el núcleo hasta que se leen desde el extremo de lectura de la tubería.
Visualizo un |
como una tubería real: una aplicación introduce datos y la otra saca datos de la cola de la tubería lo más rápido posible.
¿Qué sucede cuando el programa del lado izquierdo escribe más datos más rápido de lo que el otro lado de la tubería puede esperar procesar? ¿Causará un uso extremo de memoria o intercambio, o el núcleo intentará crear un FIFO en el disco, llenando así el disco? ¿O simplemente fallará SIGPIPE Broken pipe
si el búfer es demasiado grande?
Básicamente, esto se reduce a dos preguntas:
- ¿Cuáles son las implicaciones y los resultados de insertar más datos en una tubería de los que se leen a la vez?
- ¿Cuál es la forma confiable de comprimir un flujo de datos en el disco sin poner todo el flujo de datos sin comprimir en el disco?
Nota 1: No puedo simplemente copiar exactamente los primeros 70 GB usados y esperar obtener un sistema o sistema de archivos que funcione, debido a la fragmentación y otras cosas que requerirán que el contenido completo esté intacto.
fuente
lzop
lugar degzip
; se comprime mucho más rápido con solo una relación de compresión ligeramente inferior. Lo encuentro ideal para imágenes de disco donde la velocidad de compresión puede ser un verdadero cuello de botella.Respuestas:
Técnicamente ni siquiera necesitas
dd
:Si haces uso
dd
, siempre hay que ir con más grande que tamaño de bloque por defecto comodd bs=1M
o sufrir demonios syscall (dd
's de bloque por defecto es de 512 bytes, ya queread()
S ywrite()
s eso es4096
llamadas al sistema porMiB
, el exceso de gastos generales).gzip -9
usa MUCHO más CPU con muy poco para mostrar. Sigzip
está ralentizando, baje el nivel de compresión o use un método de compresión diferente (más rápido).Si está haciendo copias de seguridad basadas en archivos en lugar de
dd
imágenes, podría tener cierta lógica que decida si comprimir o no (no tiene sentido hacerlo para varios tipos de archivos).dar
(tar
alternativa`) es un ejemplo que tiene opciones para hacerlo.Si su espacio libre es CERO (porque es un SSD que devuelve cero de manera confiable después de TRIM y ejecutó
fstrim
y soltó cachés), también puede usarlodd
con unaconv=sparse
bandera para crear una imagen escasa, sin comprimir, montable en bucle que usa cero espacio en disco para las áreas cero . Requiere que el archivo de imagen esté respaldado por un sistema de archivos que admita archivos dispersos.Alternativamente, para algunos sistemas de archivos existen programas que solo pueden generar imágenes de las áreas utilizadas.
fuente
dd bs=1M
" - Puedes, pero no esperes demasiado. En mi PC,dd
haré unos 2GB / s con bloques de 512 bytes. Ese no será el cuello de botella;gzip
estarán.dd
2GB / s con bloques de 512 bytes, me sorprendería si no maximizara un núcleo de CPU al 100% en el proceso. Ahora, si su caja es un quadcore que de todos modos permanece inactivo, es posible que no note la diferencia. Sin embargo, todos los demás todavía lo hacen.dd
se menciona el tamaño de bloque, la gente viene a buscar cosas.gzip
ser intensivo en CPU también fue parte de mi respuesta, ¿de acuerdo? Y lo siento, no estoy de acuerdo con "insignificante". Es posible que solo agregue 1-2s por conciertogzip -9
(pero eso aún equivale a minutos cuando se procesan cientos de conciertos), pero siguiendo su consejolzop -1
es 1s por concierto versus 4s por concierto. Probado en una patata (servidor de un solo núcleo). Agregar un tamaño de bloque sanodd
no cuesta nada y tiene cero inconvenientes. No hagas trampas. Simplemente hazlo. ymmvdd
lee y escribe datos un bloque a la vez, y solo tiene un bloque pendiente. Asi quemuestra que
dd
usa aproximadamente 1 MB de memoria. Puedes jugar con el tamaño del bloque y soltarlovalgrind
para ver el efecto endd
la velocidad.Cuando entras
gzip
,dd
simplemente disminuye la velocidad para que coincidagzip
la velocidad. Su uso de memoria no aumenta, ni hace que el kernel almacene los búferes en el disco (el kernel no sabe cómo hacerlo, excepto mediante intercambio). Una tubería rota solo ocurre cuando uno de los extremos de la tubería muere; versignal(7)
ywrite(2)
para más detalles.Así
es una forma segura de hacer lo que buscas.
Al realizar la canalización, el proceso de escritura termina siendo bloqueado por el núcleo si el proceso de lectura no se mantiene. Puedes ver esto ejecutando
Verá que
dd
lee 1 MB, luego emite unwrite()
mensaje que sesleep
queda allí esperando un minuto mientras se ejecuta. Así es como se equilibran ambos lados de una tubería: el núcleo bloquea la escritura si el proceso de escritura es demasiado rápido, y bloquea las lecturas si el proceso de lectura es demasiado rápido.fuente
dd
sabe reducir la velocidad para igualargzip
la velocidad? Es automático, como el núcleo, ¿o se calcula a partir de metadatos sobre su descriptor de archivo de salida?dd
llamadaswrite()
para poner datos en la tubería.write()
en realidad transfiere el control al kernel para que pueda manipular la memoria de la tubería. Si el núcleo ve que la tubería está llena, esperará ("bloqueará") hasta que la tubería tenga suficiente espacio. Solo entonceswrite()
finalizará la llamada y volverá a transferirse el controldd
, que luego volverá a escribir datos en la tubería.No hay implicaciones negativas además del rendimiento: la tubería tiene un búfer, que generalmente es de 64K, y después de eso, una escritura en la tubería simplemente se bloqueará hasta que se
gzip
lean más datos.fuente
Respondiendo a la pregunta real sobre cómo funciona: "¿y si el programa del lado izquierdo escribe más datos más rápido de lo que el otro lado de la tubería puede esperar procesarlo?"
Esto no pasa Hay un tampón bastante pequeño y de tamaño limitado en la tubería; ver ¿Qué tan grande es el buffer de la tubería?
Una vez que el buffer de la tubería está lleno, el programa de envío se bloquea . Cuando realiza una llamada de escritura, el núcleo no devolverá el control al programa hasta que los datos se hayan escrito en el búfer. Esto le da al programa de lectura tiempo de CPU para vaciar el búfer.
fuente
Tal vez solo necesite los archivos, luego use tar. Puede llenar con ceros los bloques que no contienen nada que desee, alguien ya ha preguntado al respecto. Limpie el espacio no utilizado con ceros (ext3, ext4)
Luego, hay
pigz
cuál suele ser más rápido quegzip
.fuente