¿Por qué dd tarda demasiado?

17

Necesito copiar un disco a otro. Intenté con el comando a continuación y me lleva casi un día copiar 1 TB de disco en federo.

dd if=/dev/sda of=/dev/sdb 

He intentado lo mismo en un sistema Unix (HP-UX) con el siguiente comando y se completa en unas pocas horas

dd if=/dev/sda of=/dev/rdsk

¿Cuál es la alternativa que podría usar para copiar de disco a disco tan rápido?

KKD
fuente
2
cp /dev/sda /dev/sdbo ( pv /dev/sda > /dev/sdb para obtener una barra de progreso) sería mucho más rápido. ¿Por qué usarías ddaquí? ddsolo sería útil con cosas como conv=sync,noerrormanejar discos con errores, pero incluso entonces tendría más sentido usar cosas como ddrescue(ver también pvla -Eopción).
Stéphane Chazelas
1
@ StéphaneChazelas catpuede ser aún más rápido, pero la diferencia no es tan dramática (tal vez más grande para dispositivo a dispositivo que archivo a archivo como en mi experimento).
Gilles 'SO- deja de ser malvado'
8
"He intentado lo mismo en un sistema Unix" - Entonces, ¿en qué tipo de sistema probaste el primero, si no un Unix? Además, qué hardware, etc., yaddayadda.
marcelm
Bienvenido a la ddtrampa # 1
Dmitry Grigoryev
Usé el primero en HP-UX (Integrity blade) y también usé la máquina Solaris.
KKD

Respuestas:

28

ddtiene muchas opciones (extrañas), vea dd (1) .

Debe indicar explícitamente el tamaño del búfer, así que intente

dd if=/dev/sda of=/dev/sdb bs=16M

IIRC, el tamaño predeterminado del búfer es de solo 512 bytes. El comando anterior lo establece en 16 megabytes. Podría probar algo más pequeño (p bs=1M. Ej. ), Pero debería usar más que el predeterminado (especialmente en hardware de disco reciente con sectores de 4Kbytes, es decir, Formato avanzado ). Ingenuamente recomiendo una potencia de dos, que es al menos un megabyte.

Con el tamaño predeterminado del búfer de 512 bytes, supongo (pero podría estar muy equivocado) que el hardware requiere que el núcleo transfiera 4K por cada bloque de 512 bytes.

Al respecto rdsk, las páginas de manual de sd (4) dicen:

En este momento, solo se proporcionan dispositivos de bloque. Los dispositivos sin procesar aún no se han implementado.

El aumento del tamaño del búfer de dd le dará más rendimiento para las operaciones de lectura y escritura. Ahora todos los discos tienen memoria intermedia de lectura / escritura de hardware. Pero si aumenta el tamaño del búfer de dd más que el búfer de hardware, su rendimiento disminuirá porque dd leerá desde el primer disco al búfer cuando el segundo disco haya escrito todo desde su propio búfer de hardware. Necesita establecer la bsopción del comando dd cada vez que un valor diferente para diferentes dispositivos.

Basile Starynkevitch
fuente
Si rdsk está disponible en sistemas Linux? Lo he usado en sistemas Unix.
KKD
1
El caché de la página probablemente se distribuirá en bloques de 4Kb, haga lo que haga, pero puede controlar cuántas llamadas al sistema utiliza dd para leer ese 4Kb. Estoy seguro de que hay un tamaño de lectura por encima del cual el costo de demorar las escrituras es más costoso que las llamadas al sistema guardadas, pero no tengo idea de dónde está el punto óptimo.
Inútil
Un tamaño de bloque de unos pocos MB es mejor que el 512B predeterminado, pero cuando comparé esto , descubrí que funcionaba catigual de bien (para la transferencia de sistema de archivos a sistema de archivos, el bloqueo directo a bloque puede tener diferentes características de rendimiento). Sin embargo, la diferencia no fue dramática en ningún caso.
Gilles 'SO- deja de ser malvado'
1
Curiosamente, en macOS (un certificado por SUS, por cierto) es más rápido de usar/dev/rdiskX como objetivo cuando se realiza dd.
adib
1
en caso de que se pregunte qué está pasando (como lo hice) agregue también status=progresseso imprimirá todo el progreso de la operación.
Aleksander Lech
17

Años atrás en Unix-land ddera la forma requerida de copiar un dispositivo de bloque. Eso se ha llevado a cabo como conocimiento de culto de carga, aunque (al menos en sistemas basados ​​en Linux) cates casi siempre más rápido que dd.

Sin embargo, incluso en la historia, un tamaño de bloque decente ayudó a reducir la cantidad de llamadas (lentas) del sistema, dado que cada llamada del sistema activaba una operación de E / S. El tamaño de bloque predeterminado es 512 bytes (un sector de disco). Recolectar múltiples bloques de disco juntos en una sola lectura fue, y es, también aceptable. Este ejemplo utiliza un tamaño de bloque de 32 MB:

dd bs=$((512*2048*32)) if=/dev/source of=/dev/target

Sin embargo, en los sistemas actuales basados ​​en Linux, los discos se pueden copiar de manera más eficiente con un simple cat

cat /dev/source >/dev/target

(Como se señaló en los comentarios sobre su pregunta, pvpuede sustituirse caty le dará una indicación del progreso y el rendimiento).

roaima
fuente
3
Específicamente, la razón por la que dd tuvo que usarse fue un error en GNU cp y un error en el kernel de Linux a principios de los 90. Las razones para usar dd en sistemas históricos de Unix eran muy diferentes, y querer copiar un dispositivo de bloque completo era algo inusual.
Random832
1
@ Random832 querer copiar un disco completo hubiera sido inusual, pero sí recuerdo la necesidad de copiar particiones (grandes - 150 o incluso 200 MB)
roaima
3
(Los detalles de los errores: el núcleo informó los tamaños de uso de disco incorrectamente [lo que llevó a cp a concluir que cada archivo de origen era un archivo disperso], y cp no cerró los bloques al copiar desde un archivo disperso a un destino de dispositivo. Por lo tanto, cualquier cero bloquear en su fuente tendría cualquier basura que ya estuviera en el disco)
Random832
Me encanta este tipo de respuesta. Gracias por la info. Aquí está tu updoot.
catbadger
7

En general, ddse puede evitar a favor de algunas alternativas. Hay varias buenas razones para usar GNU en su ddrescuelugar. En Ubuntu, puedes instalarlo con:

sudo apt-get install gddrescue

y simplemente fácil ddrescuede usar. Tenga en cuenta que a diferencia del nombre del paquete, el ejecutable no tiene la inicial g.

Usarlo es tan simple como:

ddrescue inputFile outputFile logFile

El archivo de registro (llamado lo que elija) le permite pausar / detener y reiniciar, sin rehacer el trabajo anterior, lo cual es útil cuando se realizan clones grandes o la recuperación de discos. Por defecto, muestra el progreso, la velocidad de copia actual, la velocidad de copia promedio y el número de bloques defectuosos encontrados.

Utiliza valores predeterminados razonables para el tamaño de bloque, por lo que la velocidad de copia siempre es tan rápida como el dispositivo puede manejar, al menos en mi experiencia (he clonado muchos cientos de unidades con él, todos los tamaños y tipos).

Muchas veces, las unidades que comienzan a fallar tienen problemas de velocidad, como parches ocasionales de lentitud, baja velocidad promedio, pausas largas repentinas (sectores defectuosos) o reinicios completos (errores graves de la superficie). ddrescuepuede ayudarlo a identificar todo lo anterior y reiniciar su clon (siempre que haya especificado un archivo de registro) incluso si su unidad se está reiniciando.

bloque tecnico
fuente
6

Muy buena pregunta. La interfaz en bruto se implementa en algunos sistemas Unix (tru64, hpux, solaris) pero no en Linux. La interfaz sin formato hace que la transferencia sea más rápida porque se omite la E / S de Unix. La interfaz de bloque ( /dev/dsko /dev/disk) es más lenta porque usa el sistema de E / S de Unix. Para acelerar dd(gnu dd can) use bs=30Mo bs=20Mdependiendo de su hw. La respuesta corta es: NO, no está implementado, al menos hasta donde yo sé. Estoy usando Linux desde los viejos tiempos de la versión 2.2 del kernel y nunca lo he visto rdskusado en Unix.

elbarna
fuente
55
¿Por qué sugiere un tamaño de bloque que no sea una potencia de dos?
Basile Starynkevitch
2
@Basile un múltiplo del tamaño del bloque de disco es suficiente, por lo que 20MiB estaría bien.
roaima