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.imgprimero 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.
ddescribe en STDOUT de forma predeterminada y gzippuede leer desde STDIN, por lo que, en teoría, puedo escribir dd if=/dev/sdb | gzip -9 -, pero gziptarda mucho más en leer los bytes que ddpuede 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 pipesi 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

lzoplugar 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=1Mo sufrir demonios syscall (dd's de bloque por defecto es de 512 bytes, ya queread()S ywrite()s eso es4096llamadas al sistema porMiB, el exceso de gastos generales).gzip -9usa MUCHO más CPU con muy poco para mostrar. Sigzipestá 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
ddimágenes, podría tener cierta lógica que decida si comprimir o no (no tiene sentido hacerlo para varios tipos de archivos).dar(taralternativa`) 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ó
fstrimy soltó cachés), también puede usarloddcon unaconv=sparsebandera 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,ddharé unos 2GB / s con bloques de 512 bytes. Ese no será el cuello de botella;gzipestarán.dd2GB / 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.ddse menciona el tamaño de bloque, la gente viene a buscar cosas.gzipser 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 -1es 1s por concierto versus 4s por concierto. Probado en una patata (servidor de un solo núcleo). Agregar un tamaño de bloque sanoddno cuesta nada y tiene cero inconvenientes. No hagas trampas. Simplemente hazlo. ymmvddlee y escribe datos un bloque a la vez, y solo tiene un bloque pendiente. Asi quemuestra que
ddusa aproximadamente 1 MB de memoria. Puedes jugar con el tamaño del bloque y soltarlovalgrindpara ver el efecto enddla velocidad.Cuando entras
gzip,ddsimplemente disminuye la velocidad para que coincidagzipla 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
ddlee 1 MB, luego emite unwrite()mensaje que sesleepqueda 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
ddsabe reducir la velocidad para igualargzipla velocidad? Es automático, como el núcleo, ¿o se calcula a partir de metadatos sobre su descriptor de archivo de salida?ddllamadaswrite()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
gziplean 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
pigzcuál suele ser más rápido quegzip.fuente