Por que o dd demora muito?

17

Eu preciso copiar um disco para outro. Eu tentei com o comando abaixo e leva quase um dia para copiar 1 TB de disco no federo.

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

Tentei o mesmo em um sistema Unix (HP-UX) com o comando abaixo e ele é concluído dentro de algumas horas

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

Qual é a alternativa que eu poderia usar para copiar de disco para disco o mais rápido?

KKD
fonte
2
cp /dev/sda /dev/sdbou ( pv /dev/sda > /dev/sdb para obter uma barra de progresso) seria muito mais rápido. Por que você usaria ddaqui? ddseria útil apenas em coisas como conv=sync,noerrormanipular discos com erros, mas mesmo assim faria mais sentido usar coisas como essas ddrescue(veja também pva -Eopção de).
Stéphane Chazelas
1
@ StéphaneChazelas catpode ser ainda mais rápido, mas a diferença não é tão dramática (talvez maior para dispositivo para dispositivo que arquivo para arquivo, como no meu experimento).
Gilles 'SO- stop be evil'
8
"Eu tentei o mesmo em um sistema Unix" - Então, em que tipo de sistema você tentou o primeiro, senão um Unix? Além disso, qual hardware, etc, yaddayadda.
marcelm
Bem-vindo à ddarmadilha # 1
Dmitry Grigoryev
Utilizou o primeiro no HP-UX (blade Integrity) e o Solaris usado anteriormente.
KKD

Respostas:

27

ddtem muitas opções (estranhas), veja dd (1) .

Você deve declarar explicitamente o tamanho do buffer, então tente

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

IIRC, o tamanho padrão do buffer é de apenas 512 bytes. O comando acima o define para 16 megabytes. Você pode tentar algo menor (por exemplo bs=1M), mas deve usar mais do que o padrão (especialmente em hardware de disco recente com setores de 4Kbytes, ou seja, Formato Avançado ). Ingenuamente, recomendo uma potência de dois, que é pelo menos um megabyte.

Com o tamanho padrão do buffer de 512 bytes, acho (mas posso estar muito errado) que o hardware exige que o kernel transfira 4K para cada bloco de 512 bytes.

A respeito rdsk, as páginas de manual do sd (4) dizem:

No momento, apenas dispositivos de bloco são fornecidos. Os dispositivos brutos ainda não foram implementados.

O aumento do tamanho do buffer do dd fornecerá mais desempenho para operações de leitura e gravação. Agora todos os discos possuem buffer de leitura / gravação de hardware. Mas se você aumentar o tamanho do buffer do dd mais do que o buffer do hardware, seu desempenho diminuirá porque o dd lerá do primeiro disco para o buffer quando o segundo disco tiver gravado tudo a partir de seu próprio buffer de hardware. Você precisa definir a bsopção do comando dd sempre que um valor diferente para dispositivos diferentes.

Basile Starynkevitch
fonte
Se o rdsk está disponível nos sistemas Linux? Eu usei em sistemas Unix.
KKD
1
O cache da página provavelmente lidará com blocos de 4Kb, independentemente do que você faça, mas você pode controlar quantos syscalls o dd usa para ler esse 4Kb. Tenho certeza de que há algum tamanho de leitura acima do qual o custo de gravações paralisadas é mais caro que os syscalls salvos, mas não faço ideia de onde está o ponto ideal.
Inútil:
Um tamanho de bloco de alguns MB é melhor que o 512B padrão, mas, quando comparamos isso , descobri que funcionava cattão bem (para transferência de sistema de arquivos para sistema de arquivos, bloco a bloco direto pode ter características de desempenho diferentes). No entanto, a diferença não foi dramática em nenhum caso.
Gilles 'SO- stop be evil'
1
Curiosamente, no macOS (certificado pelo SUS, btw), é mais rápido usar/dev/rdiskX como destino durante o desempenho dd.
adib
1
caso você queira saber o que está acontecendo (como eu fiz), adicione também status=progressque imprimirá todo o progresso da operação.
Aleksander Lech
16

Anos atrás, no Unix-land, ddera a maneira necessária de copiar um dispositivo de bloco. Isso avançou como conhecimento do culto à carga, embora (em sistemas baseados em Linux, pelo menos) catseja quase sempre mais rápido que dd.

No entanto, mesmo no histórico, um tamanho de bloco decente ajudou a reduzir o número de chamadas (lentas) do sistema, uma vez que cada chamada do sistema acionava uma operação de E / S. O tamanho padrão do bloco é 512 bytes (um setor de disco). A coleta de vários blocos de disco em uma única leitura também foi - e é - aceitável. Este exemplo usa um tamanho de bloco de 32 MB:

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

Nos sistemas atuais baseados em Linux, os discos podem ser copiados com mais eficiência com um simples cat

cat /dev/source >/dev/target

(Conforme observado nos comentários da sua pergunta, pvpode ser substituído cate fornecerá uma indicação do progresso e da taxa de transferência.)

roaima
fonte
2
Especificamente, o motivo pelo qual o dd teve que ser usado foi um bug no GNU cp e um bug no kernel do linux no início dos anos 90. As razões para usar o dd em sistemas históricos unix eram muito diferentes, e querer copiar um dispositivo de bloco inteiro era algo incomum a se fazer.
Random832
1
@ Random832 querendo copiar um disco inteiro teria sido incomum, mas eu me lembro a necessidade de copiar partições ao redor (big ones - 150 ou até 200MB)
roaima
2
(As especificidades dos bugs: o kernel relatou os tamanhos de uso do disco incorretamente [levando o cp a concluir que todo arquivo de origem era um arquivo esparso] e o cp não zera os blocos ao copiar de um arquivo esparso para um destino de dispositivo. Portanto, zero bloco em sua fonte teria qualquer que seja lixo passou a ser já no disco)
Random832
Eu amo esse tipo de resposta. Obrigado pela informação. Aqui está o seu updoot.
catbadger
7

Geralmente, ddpode ser evitado em favor de algumas alternativas. Existem várias boas razões para usar o GNU ddrescue. No Ubuntu, você pode instalá-lo com:

sudo apt-get install gddrescue

e simples ddrescuede usar. Observe que, diferentemente do nome do pacote, o executável não possui a inicial g.

Usá-lo é tão simples quanto:

ddrescue inputFile outputFile logFile

O arquivo de log (com o nome que você escolher) permite pausar / parar e reiniciar, sem refazer o trabalho anterior, o que é útil ao fazer clones grandes ou recuperar discos. Por padrão, ele exibe o progresso, a velocidade atual da cópia, a velocidade média da cópia e o número de blocos inválidos encontrados.

Ele usa padrões sensíveis para o tamanho do bloco, portanto, a velocidade da cópia é sempre a mais rápida que o dispositivo pode suportar, pelo menos na minha experiência (eu já clonei muitas centenas de unidades com todos os tamanhos e tipos).

Muitas vezes, as unidades que estão começando a falhar apresentam problemas de velocidade, como manchas ocasionais de lentidão, baixa velocidade média, pausas longas repentinas (setores defeituosos) ou redefinições completas (erros graves de superfície). ddrescuepode ajudá-lo a identificar todas as opções acima e reiniciar seu clone (desde que você tenha especificado um arquivo de log), mesmo que sua unidade esteja se redefinindo.

técnico
fonte
6

Muito boa pergunta. A interface bruta é implementada em alguns sistemas unix (tru64, hpux, solaris), mas não no linux. A interface bruta facilita a transferência porque a E / S unix é ignorada. A interface do bloco ( /dev/dskou /dev/disk) é mais lenta porque usa o sistema de E / S unix. Para acelerar dd(gnu dd can) use bs=30Mou bs=20Mdependendo do seu hw. A resposta curta é: NÃO, não está implementada, pelo menos até onde eu sei. Estou usando o linux desde os tempos antigos da versão 2.2 do kernel e nunca vi isso rdskusado no unix.

elbarna
fonte
5
Por que você sugere um tamanho de bloco que não é uma potência de dois?
Basile Starynkevitch
2
@ Como um múltiplo do tamanho do bloco de disco é suficiente, então 20MiB seria bom.
roaima