
Preciso resgatar dados de um disco rígido grande de 2 TB e estou fazendo isso em algum Live-Linux em alguma VM, onde o disco rígido problemático está conectado usando USB 3 e a VM fornece um disco virtual do tamanho necessário localmente para receber os dados. Em seguida, executei a seguinte chamada, simplesmente para ver como estavam as coisas:
ddrescue -f /dev/sdc /dev/sdb /mnt/sda1/ddrescue.map
sdc
é o dispositivo quebrado no USB, sdb
é o disco virtual para receber os dados, sda1
é para armazenamento temporário e formatado usando Ext4.
As coisas começaram a funcionar rapidamente, ddrescue
consegui ler cerca de 45 GB de dados em minutos, depois as coisas ficaram muito mais lentas, lendo apenas alguns bytes por segundo durante dias. Portanto, o dispositivo estava obviamente quebrado nessas partes e tentei simplesmente ignorá-las usando várias invocações diferentes, --input-position=[...]GB
uma após a outra. Dependendo de onde eu pulei, as coisas começaram a ler rápido novamente, até que ficaram lentas novamente e eu pulei novamente usando outra invocação. O importante a notar é que as posições de entrada e saída impressas ddrescue
sempre estiveram sincronizadas! Eu também não alterei nada manualmente no arquivo de mapa fornecido, nem o excluí ou algo assim, ele sempre foi o mesmo arquivo e gerenciado apenas por ddrescue
si mesmo.
Depois mudei um pouco a abordagem e decidi não usar --input-position
mais manualmente, mas sim o seguinte:
ddrescue -f --min-read-rate=1MB --skip-size=1MB /dev/sdc /dev/sdb /mnt/sda1/ddrescue.map
Portanto, sempre que ddrescue
reconhecia partes lentas, ele ignorava blocos de dados razoavelmente quebrados e continuava a leitura. Novamente, as posições de entrada e saída estavam sincronizadas e o contador de dados lidos e resgatados aumentava o tempo todo. Até o ponto foram ddrescue
concluídos e disseram ter resgatado cerca de 650 GB de dados.
O problema é que, depois de finalmente examinar os próprios arquivos do disco virtual, parece que apenas cerca de 160 GB de dados estão realmente armazenados. Além disso, o carimbo de data/hora da última gravação era antigo há alguns dias. Então, por algum motivo, ddrescue
pensei que estava lendo muitos dados, mas não parecia gravá-los corretamente nos locais do disco virtual onde os lia do disco quebrado. No final das contas, pelo que entendi, o disco virtual deveria ter pelo menos o tamanho ddrescue
mencionado sobre a quantidade de dados que resgatou.
Tenho a sensação de que ddrescue
li corretamente todos os dados mencionados, mas simplesmente substituí os dados já resgatados em invocações subsequentes. Então, embora eu ache que foi reconhecido --input-position
como leitura, parece ter escrito sempre começando na posição 0 novamente no alvo.
Obviamente eu não especifiquei a posição inicial para gravar os dados, mas de acordo com odocumentosisso não deveria ser necessário e ddrescue
sempre imprimiu a posição de entrada e saída como a mesma.
-o bytes
--output-position=bytes
Starting position of the image of the rescue domain in outfile, in bytes.
Defaults to '--input-position'. The bytes below bytes aren't touched if
they exist and truncation is not requested. Else they are set to 0.
É claro que não solicitei o truncamento, de acordo com a documentação ele não está habilitado por padrão e nem funcionaria para a unidade de destino que especifiquei:
-t
--truncate
Truncate outfile to zero size before writing to it. Only works for regular
files, not for drives or partitions.
Então, alguma ideia do que pode ter dado errado? Minhas múltiplas invocações com valores diferentes para --input-position
errado já estavam erradas? Isso tem a ver com leitura e gravação em unidades em vez de partições ou arquivos?
Talvez seja um problema ao gravar em algum disco virtual? Embora eu não veja por que isso deveria fazer alguma diferença e preciso gravar em algum disco virtual e não posso fornecer armazenamento bruto do dispositivo com o tamanho necessário.
Obrigado!
Responder1
É seguro usar vários diferentes
--input-position
com o ddrescue?
Parece que perdi esse exemplo antes, mas foi isso que fiz e sugere que minha abordagem é suportada:
Example 5: While rescuing a partition in /dev/sda1 to the file hdimage, /dev/sda1 stops responding and begins returning read errors, causing ddrescue to mark the rest of the partition as non-scraped.
ddrescue -n /dev/sda1 hdimage mapfile <-- /dev/sda1 fails here
(restart /dev/sda or reboot computer)
ddrescue -n -A -i<pos> -O /dev/sda1 hdimage mapfile
(if /dev/sda1 fails again, restart /dev/sda or reboot computer and
then repeat the above command as many times as needed until it
succeeds. <pos> is the position where the drive stopped responding)
ddrescue -d -r3 /dev/sda1 hdimage mapfile
https://www.gnu.org/software/ddrescue/manual/ddrescue_manual.html#Examples
A segunda invocação está claramente documentada para ser repetida com diferentes posições. Quanto ao ddrescue
funcionamento do seu arquivo de mapa, isso também faz sentido, simplesmente porque ele sempre sabe através desse arquivo quais blocos já foram lidos.
Portanto, parece que há grandes chances de que o problema no meu caso seja diferente, especialmente o carimbo de data/hora muito antigo que acho estranho. Talvez eu simplesmente tenha perdido mensagens que ddrescue
não estão sendo gravadas no dispositivo de destino real por algum motivo. A própria VM também estava em outra unidade USB, talvez tenha havido alguns erros de conexão que fizeram com que o dispositivo fosse perdido pelo Live-Linux durante o tempo de execução ou algo assim. Eu poderia facilmente ter perdido esses erros por dmesg -T
causa de todos os erros de leitura registrados.
Parece que preciso repetir todo o processo...
Responder2
Li o ddrescue
manual e em nenhum lugar menciona a possibilidade de múltiplos input-position
parâmetros.
Este parâmetro é sempre mencionado como "a" ou "the", então parece que deve ser único.
A origem do seu problema pode ser esta frase do manual:
Observe que você deve manter o deslocamento original entre '--input-position' e '--output-position' da execução de resgate original.
Isto parece concordar com o seguinte parágrafo:
Ddrescue não grava zeros na saída quando encontra setores defeituosos na entrada e não trunca o arquivo de saída se não for solicitado. Assim, toda vez que você executa no mesmo arquivo de saída, ele tenta preencher as lacunas sem apagar os dados já resgatados.
Isso significa que ele ddrescue
lembra os parâmetros da primeira execução, então você deve sempre manter os mesmos parâmetros, ou talvez apenas não especificá-los nas execuções subsequentes (não posso dizer o que está certo). É perfeitamente possível que alguns parâmetros tenham sido lembrados e os novos tenham sido ignorados nas execuções seguintes.
Se partes das metatabelas do disco foram danificadas, você poderá ver menos dados do que os realmente recuperados, porque nenhum arquivo parece incluir essas partes.
Os dados que ddrescue
não podem ser recuperados precisam ser recuperados por outros produtos de recuperação. Isto pode demorar muito e pode até ser impossível para os produtos à sua disposição. Se for absolutamente necessário recuperar os dados, uma empresa de recuperação profissional poderá fazê-lo a partir do disco original, mas esses serviços são caros.
Responder3
Como a página de manual do ddrescue
é longa, o uso do ddrescue
é muito diferente de acordo com o objetivo e o nível do usuário. Basicamente, se você usa o Live Linux, é melhor executá-lo na máquina física em vez da VM, e também conectar o disco ao SATA sem qualquer adaptador SATA/USB.
Entre os outros recursos, ddrescue
pode-se ignorar o driver de disco do kernel e os buffers, reduzindo assim a leitura repetida e inútil de clusters defeituosos. O mapfile (anteriormente chamado de logfile) mantém informações sobre todos os clusters de leitura sem sucesso e é por isso que você pode simplesmente repetir a etapa com falha. O ddrescue
busca pelo mapfile antes de iniciar seu trabalho, cria-o, se não existir, lê-o, se estiver disponível e começa a continuar o trabalho de resgate na última posição registrada. Você não precisa mover a posição inicial manualmente toda vez que o programa trava!
Você pode usar várias opções para tornar o processo de resgate mais rápido e seguro. Você também pode, e é recomendado, fazer o processo de resgate em duas ou mais etapas:
Primeiro passo: leia rapidamente os clusters bons e pule imediatamente o cluster ruim.
Segunda etapa: lide com clusters não lidos da etapa anterior e use opções especiais para modificar os recursos do disco (NCQ, leitura antecipada ...) para ler um setor de uma vez. Os comandos adequados (eu uso):
ddrescue -n -p -d -r1 /dev/sdd $IMGPATH/disk.img $IMGPATH/disk.log;
ddrescue -d -r3 -R /dev/sdd $IMGPATH/disk.img $IMGPATH/disk.log;
# | | | | |
# | | | | revers reading
# | | | retry read 1x (3x)
# | | direct access to disk (bypass the kernel)
# | preallocate diskspace
# nonscrap
Se o seu disco esquenta muito ou não gosta de muitas operações de leitura, você pode desacelerar a leitura com a opção:--max-read-rate=50M
Então isso é apenas para o primeiro toque, mas você pode encontrar muitos conselhos em clubes ou fóruns especializados sobre o assunto ddrescue
.