Tenho um HD de 320 GB com setores defeituosos e o disco está falhando devido a erros de leitura, relatados via smartctl
. Para economizar o máximo de dados, eu queria executar dd
/ ddrescue
neste disco.
ddrescue
tinha uma velocidade de leitura extremamente lenta nas configurações padrão (300 kB/s) desde o início e não tive tempo para experimentar as configurações, então optei por dd
. Vamos pular o tópico de melhorar a velocidade do ddrescue por enquanto.
Usei dd
o comando, copiando para um SSD com >1 TB de espaço livre:
dd if=/dev/sda of=recovery.img conv=noerror,sync iflag=fullblock status=progress
O problema é que, quanto mais tempo dd
passa, mais lento ele fica. Começou com 10 MB/s, caiu rapidamente para 5 MB/s e continua diminuindo. É compreensível que, ao ler blocos defeituosos, eu obtenha velocidade mais lenta e erros de leitura, mas a velocidade nunca se recupera e nunca aumenta, mesmo quando não há erros por muitos gigabytes. Exemplo de saída:
36571460608 bytes (37 GB, 34 GiB) copied, 7521 s, 4.9 MB/s
dd: error reading '/dev/sda': Input/output error
71428640+0 records in
71428640+0 records out
36571463680 bytes (37 GB, 34 GiB) copied, 7522.87 s, 4.9 MB/s
[a lot of read errors here]
163873310720 bytes (164 GB, 153 GiB) copied, 55200 s, 3.0 MB/s
dd: error reading '/dev/sda': Input/output error
320065087+1 records in
320065088+0 records out
163873325056 bytes (164 GB, 153 GiB) copied, 55202.2 s, 3.0 MB/s
[a lot of read errors here]
180528095744 bytes (181 GB, 168 GiB) copied, 105746 s, 1.7 MB/s
dd: error reading '/dev/sda': Input/output error
352593785+152 records in
352593937+0 records out
180528095744 bytes (181 GB, 168 GiB) copied, 105748 s, 1.7 MB/s
184232141312 bytes (184 GB, 172 GiB) copied, 115892 s, 1.6 MB/s
184232509952 bytes (184 GB, 172 GiB) copied, 115893 s, 1.6 MB/s
192463561216 bytes (192 GB, 179 GiB) copied, 138368 s, 1.4 MB/s
211374223872 bytes (211 GB, 197 GiB) copied, 190337 s, 1.1 MB/s
dd: error reading '/dev/sda': Input/output error
412840143+153 records in
412840296+0 records out
211374231552 bytes (211 GB, 197 GiB) copied, 190342 s, 1.1 MB/s
211374232064 bytes (211 GB, 197 GiB) copied, 190342 s, 1.1 MB/s
dd: error reading '/dev/sda': Input/output error
412840143+154 records in
412840297+0 records out
211374232064 bytes (211 GB, 197 GiB) copied, 190344 s, 1.1 MB/s
No exemplo acima, entre 181 GB e 211 GB não houve erros de leitura, então muitos setores deveriam estar ok, mas a velocidade nunca aumentou para ~10 MB/s, continuava caindo. Também não houve erros de leitura nos primeiros 37 GB (portanto, faltando saída), mas aqui a queda de velocidade é compreensível devido ao esgotamento do cache e à falha do disco.
hdparm usa configurações ideais para velocidade de disco. iostat relata que o disco está sendo utilizado 100%:
r/s rkB/s rrqm/s %rrqm r_await rareq-sz Device
89.50 358.0k 0.00 0.0% 11.12 4.0k sda
w/s wkB/s wrqm/s %wrqm w_await wareq-sz Device
0.00 0.0k 0.00 0.0% 0.00 0.0k sda
d/s dkB/s drqm/s %drqm d_await dareq-sz Device
0.00 0.0k 0.00 0.0% 0.00 0.0k sda
f/s f_await aqu-sz %util Device
0.00 0.00 0.99 99.5% sda
Minha pergunta é: por que algo assim acontece? Como é possível que a velocidade de leitura do disco fique cada vez mais lenta com o tempo, mesmo sem erros de leitura de blocos defeituosos? Por que a velocidade nunca aumenta?
Segunda parte da pergunta: É possível ddrescue
ter velocidade melhor do que dd
para setores bons?
O número de " velocidade " que você parece estar observando não representa o que você pensa. Os números que você parece estar analisando são um valor de throughput geral ; é o quociente do total de bytes transferidos dividido pelo tempo total decorrido . Esses valores são cumulativos e não instantâneos.
Por exemplo:
36571 MB / 7523 seg = 4,86 MB/seg
E
211374 MB / 190344 seg = 1,11 MB/seg
Esses cálculos usam valores cumulativos
para gerar uma média. Um erro de leitura causa novas tentativas da operação de leitura. Isso aumenta o componente de tempo e reduz a taxa de transferência.
Referir-se a esses números de taxa de transferência como " velocidade " pode ser enganoso.
Eles não indicam nenhuma taxa real de transferência de dados em nenhuma interface.
Você não está analisando esses resultados corretamente; a saída não é periódica.
Os primeiros 164 GB de transferências têm apenas 2 relatórios, mas os próximos 48 GB produzem 11 relatórios.
Os últimos 10 GB (desses 48 GB) de transferências geram 5 (desses 11) relatórios.
A taxa de transferência média cai porque tentativas de leitura e/ou blocos inválidos estão ocorrendo com mais frequência!
Adenda
Talvez o que você considere " setores bons " não seja exato.
A mera ausência de " erros " não é um indicador bom ou confiável da integridade dos dados e/ou da saúde da unidade.
" Erros " em dispositivos de armazenamento (que utilizam ECC) não são necessariamente preto no branco; existem erros corrigíveis, bem como erros incorrigíveis.
Uma solicitação de leitura normalmente é considerada incorreta (ou seja, com falha) somente após a unidade ter realizado N tentativas e os dados ainda serem incorrigíveis. São essas tentativas repetidas de leitura do setor que aumentam o tempo operacional (pelo menos uma volta do prato por tentativa) e reduzem a taxa de transferência , e é por isso que o conceito de " velocidade " pode ser inadequado.
Quando uma dessas tentativas de leitura é boa ou (mais provavelmente) apresenta erros corrigíveis (usando o ECC), a operação de leitura é considerada concluída e bem-sucedida. O host recebe um status indicando se os dados do setor precisaram ser corrigidos, mas não sei se a contagem de tentativas é retornada.
Independentemente disso , o dd não relata nenhum erro para uma solicitação de leitura que retorna dados de setor válidos, apesar do tempo prolongado para obtê-los.
Portanto, um número de taxa de transferência deflacionado pode ser mantido baixo (ou reduzido ainda mais) por leituras "lentas" que exigem novas tentativas e não geram nenhuma mensagem de erro.
Você pode obter uma visão melhor da saúde e da capacidade de transferência do seu disco usando uma transferência (muito) menor.
Em vez de ler o disco inteiro, leia apenas um pequeno e selecionado intervalo de blocos.
onde
<início> é o LBA (número do "setor") de onde a transferência começa
<comprimento> é o número de blocos/setores a serem transferidos, por exemplo, 16 ou até 1.
Consulte também os atributos SMART da sua unidade para obter estatísticas de erros de leitura corrigidos e não corrigidos.
Três fatores: