
Necesito rescatar datos de un disco duro grande de 2 TB y lo estoy haciendo en algún Live-Linux en alguna VM, donde el disco duro problemático está conectado mediante USB 3 y la VM proporciona un disco virtual del tamaño necesario localmente para recibir los datos. Luego ejecuté la siguiente llamada, simplemente para ver cómo iban las cosas:
ddrescue -f /dev/sdc /dev/sdb /mnt/sda1/ddrescue.map
sdc
es el dispositivo USB roto, sdb
es el disco virtual para recibir los datos, sda1
es para almacenamiento temporal y está formateado usando Ext4.
Las cosas empezaron a funcionar rápidamente, ddrescue
pude leer ~45 GB de datos en cuestión de minutos, luego las cosas se ralentizaron enormemente y leyeron solo algunos bytes por segundo durante días. Entonces, el dispositivo obviamente estaba roto en estas partes y traté simplemente de omitirlas usando múltiples invocaciones diferentes, --input-position=[...]GB
una tras otra. Dependiendo de dónde salté, las cosas empezaron a leerse rápido nuevamente, hasta que volvieron a ralentizarse y salté nuevamente usando otra invocación. Lo importante a tener en cuenta es que la posición de entrada y salida impresa ddrescue
siempre ha estado sincronizada. Tampoco cambié nada manualmente en el archivo de mapa proporcionado ni lo eliminé o lo que sea, siempre ha sido el mismo archivo y solo se administra por ddrescue
sí mismo.
Luego cambié un poco el enfoque y decidí no usar --input-position
más manualmente, sino lo siguiente:
ddrescue -f --min-read-rate=1MB --skip-size=1MB /dev/sdc /dev/sdb /mnt/sda1/ddrescue.map
Entonces, cada vez que ddrescue
reconocía partes lentas, omitía bloques de datos rotos razonables y continuaba leyendo. Nuevamente, la posición de entrada y salida estaba sincronizada y el contador de datos leídos y rescatados aumentaba todo el tiempo. Hasta ese momento se ddrescue
terminó y se dijo que se habían rescatado ~650 GB de datos.
El problema es que después de mirar finalmente los archivos del disco virtual, parece que en realidad solo se almacenan ~160 GB de datos. Además, la última marca de tiempo de escritura tenía algunos días de antigüedad. Entonces, por alguna razón, ddrescue
pensé que estaba leyendo muchos datos, pero no pareció escribirlos correctamente en los lugares del disco virtual donde los leyó desde el disco roto. Al final, según tengo entendido, el disco virtual debería haber tenido al menos el tamaño ddrescue
indicado sobre la cantidad de datos que rescató.
Tengo la sensación de que ddrescue
leyó correctamente todos los datos que decía, pero simplemente sobrescribió datos ya rescatados en invocaciones posteriores. Entonces, aunque supongo que reconoció --input-position
la lectura, parece haber escrito siempre comenzando en la posición 0 nuevamente en el objetivo.
Obviamente no especifiqué la posición inicial para escribir datos, pero de acuerdo condocumentoseso no debería ser necesario y ddrescue
siempre se imprime la posición de entrada y salida para que sea la misma de todos modos.
-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.
Por supuesto, no solicité el truncamiento; según los documentos, no está habilitado de forma predeterminada y ni siquiera habría funcionado para la unidad de destino que había especificado:
-t
--truncate
Truncate outfile to zero size before writing to it. Only works for regular
files, not for drives or partitions.
Entonces, ¿alguna idea de qué pudo haber salido mal? ¿Mis múltiples invocaciones con diferentes valores --input-position
ya estaban equivocadas? ¿Tiene que ver con leer y escribir en unidades en lugar de particiones o archivos?
¿Quizás haya un problema al escribir en algún disco virtual? Aunque no veo por qué eso debería hacer alguna diferencia y necesito escribir en algún disco virtual y no puedo proporcionar almacenamiento sin formato en el dispositivo del tamaño necesario.
¡Gracias!
Respuesta1
¿Es seguro utilizar varios tipos diferentes
--input-position
con ddrescue?
Parece que me he perdido ese ejemplo antes, pero eso es en realidad lo que hice y sugiere que mi enfoque es compatible:
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#Ejemplos
Está claramente documentado que la segunda invocación se repetirá con diferentes posiciones. En cuanto a cómo ddrescue
funciona usando su archivo de mapa, esto también tiene sentido, simplemente porque usando ese archivo siempre sabe qué bloques ya han sido leídos.
Por lo tanto, parece que hay muchas posibilidades de que el problema en mi caso sea diferente, especialmente la marca de tiempo demasiado antigua que creo que reconocí es extraña. Tal vez simplemente me perdí mensajes que ddrescue
no se escriben en el dispositivo de destino real por alguna razón. La máquina virtual en sí también estaba en otra unidad USB, tal vez hubo algunos errores de conexión que hicieron que Live-Linux perdiera el dispositivo durante el tiempo de ejecución o algo así. Fácilmente podría haber pasado por alto esos errores dmesg -T
debido a todos los errores de lectura registrados.
Parece que necesito repetir todo el proceso...
Respuesta2
Leí el ddrescue
manual y en ninguna parte menciona la posibilidad de múltiples input-position
parámetros.
Este parámetro siempre se menciona como "a" o "the", por lo que parece que debe ser único.
El origen de tu problema puede ser esta frase del manual:
Tenga en cuenta que debe mantener el desplazamiento original entre '--input-position' y '--output-position' de la ejecución de rescate original.
Esto parece estar de acuerdo con el siguiente párrafo:
Ddrescue no escribe ceros en la salida cuando encuentra sectores defectuosos en la entrada y no trunca el archivo de salida si no se le solicita. Por lo tanto, cada vez que lo ejecuta en el mismo archivo de salida, intenta llenar los espacios en blanco sin borrar los datos ya rescatados.
Esto significa que ddrescue
recuerda los parámetros de la primera ejecución, por lo que se supone que siempre debes mantener los mismos parámetros, o tal vez simplemente no especificarlos en ejecuciones posteriores (no puedo decir cuál es la correcta). Es muy posible que se hayan recordado algunos parámetros y que los nuevos se hayan ignorado en las siguientes ejecuciones.
Si partes de las metatablas del disco estaban dañadas, es posible que vea menos datos de los que realmente se recuperaron, porque ningún archivo parece incluir estas partes.
Los datos que ddrescue
no se pueden recuperar deben recuperarse mediante otros productos de recuperación. Esto puede llevar mucho tiempo e incluso resultar imposible para los productos que tienes a tu disposición. Si es absolutamente necesario recuperar los datos, una empresa de recuperación profesional podría hacerlo desde el disco original, pero estos servicios son costosos.
Respuesta3
Como la página de manual de ddrescue
es larga, el uso de ddrescue
es muy diferente según el objetivo y el nivel de usuario. Básicamente, si usa Live Linux, será mejor que lo ejecute en la máquina física en lugar de en la VM, y también conecte el disco a SATA sin ningún adaptador SATA/USB.
Entre otras características, ddrescue
puede omitir el controlador de disco del núcleo y los buffers, por lo que puede reducir la lectura repetida e inútil de clústeres defectuosos. El archivo de mapa (anteriormente llamado archivo de registro) mantiene información sobre todos los clústeres de lectura fallida o exitosa y es por eso que simplemente puede repetir el paso fallido. Busca ddrescue
el archivo de mapa antes de comenzar su trabajo, lo crea, si no existe, lo lee, si está disponible y comienza a continuar el trabajo de rescate en la última posición registrada. ¡No es necesario mover la posición inicial manualmente cada vez que el programa falla!
Puede utilizar varias opciones para que el proceso de rescate sea más rápido y seguro. También puedes, y es recomendable, realizar el proceso de rescate en dos o más pasos:
Primer paso: lea rápidamente los grupos buenos y omita inmediatamente los malos.
Segundo paso: ocúpese de los clústeres no leídos del paso anterior y utilice opciones especiales para engañar las funciones del disco (NCQ, lectura anticipada...) para poder leer un sector a la vez. Los comandos adecuados (yo 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
Si su disco se calienta demasiado o no le gustan muchas operaciones de lectura, puede ralentizar la lectura con la opción:--max-read-rate=50M
Esto es sólo para el primer toque, pero puedes encontrar muchos consejos en clubes o foros especializados sobre el tema ddrescue
.