
Мне нужно спасти данные с жесткого диска объемом 2 ТБ, и я делаю это в Live-Linux в виртуальной машине, где проблемный жесткий диск подключен с помощью USB 3, а виртуальная машина предоставляет виртуальный диск нужного размера локально для получения данных. Затем я выполнил следующий вызов, просто чтобы посмотреть, как идут дела:
ddrescue -f /dev/sdc /dev/sdb /mnt/sda1/ddrescue.map
sdc
сломанное устройство USB, sdb
виртуальный диск для приема данных, sda1
предназначен для временного хранения и отформатирован с использованием Ext4.
Все начало работать быстро, ddrescue
удалось прочитать ~45 ГБ данных за несколько минут, затем все сильно замедлилось, считывая только несколько байт в секунду в течение нескольких дней. Так что устройство, очевидно, было сломано в этих частях, и я попытался просто пропустить их, используя несколько вызовов разных --input-position=[...]GB
один за другим. В зависимости от того, куда я переходил, все снова начинало быстро читать, пока снова не становилось медленно, и я снова переходил, используя другой вызов. Важно отметить, что входная и выходная позиция, напечатанная, ddrescue
всегда были синхронизированы! Я также ничего вручную не менял в предоставленном файле карты, не удалял его или что-то еще, это всегда был один и тот же файл и управлялся сам по ddrescue
себе.
После этого я немного изменил подход и решил --input-position
больше не использовать ручной режим, а вместо этого сделать следующее:
ddrescue -f --min-read-rate=1MB --skip-size=1MB /dev/sdc /dev/sdb /mnt/sda1/ddrescue.map
Поэтому всякий раз, когда ddrescue
распознавались медленные части, он пропускал разумные сломанные блоки данных и продолжал чтение. Опять же, входная и выходная позиция были синхронизированы, а счетчик прочитанных и спасенных данных все время увеличивался. До того момента, как были ddrescue
завершены и, как говорят, спасены ~650 ГБ данных.
Проблема в том, что после того, как мы наконец посмотрели на сами файлы виртуального диска, оказалось, что на самом деле хранится только ~160 ГБ данных. Кроме того, последняя временная метка записи была на несколько дней старше. Поэтому по какой-то причине ddrescue
он подумал, что считывает много данных, но, похоже, не записал их должным образом в те места на виртуальном диске, где он считывал их со сломанного диска. В конце концов, насколько я понимаю, виртуальный диск должен был иметь по крайней мере размер, ddrescue
указывающий на объем спасенных им данных.
У меня такое чувство, что он ddrescue
правильно прочитал все данные, которые он сказал, но просто перезаписал уже спасенные данные в последующих вызовах. Так что, хотя я предполагаю, что он распознал, --input-position
откуда читать, похоже, он всегда писал, начиная с позиции 0 снова в цели.
Очевидно, я не указал начальную позицию для записи данных, но согласнодокументыв этом нет необходимости, и ddrescue
в любом случае входная и выходная позиции всегда будут одинаковыми.
-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.
Конечно, я не запрашивал усечение, согласно документации, оно не включено по умолчанию и даже не сработало бы для указанного мной целевого диска:
-t
--truncate
Truncate outfile to zero size before writing to it. Only works for regular
files, not for drives or partitions.
Итак, есть идеи, что могло пойти не так? Мои множественные вызовы с разными значениями --input-position
уже были неправильными? Это связано с чтением и записью на диски вместо разделов или файлов?
Может быть, проблема с записью на какой-то виртуальный диск? Хотя я не вижу, почему это должно иметь значение, и мне нужно записать на какой-то виртуальный диск, и я не могу предоставить сырое устройство хранения необходимого размера.
Спасибо!
решение1
Безопасно ли использовать несколько разных файлов
--input-position
с ddrescue?
Кажется, я пропустил этот пример раньше, но на самом деле я именно это и сделал, и это говорит о том, что мой подход поддерживается:
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#Примеры
Второй вызов явно документирован для повторения с разными позициями. Что касается того, как ddrescue
работает с использованием его файла карты, это также имеет смысл, просто потому, что он всегда знает, используя этот файл, какие блоки уже были прочитаны.
Так что, похоже, велика вероятность, что проблема в моем случае в другом, особенно странная слишком старая временная метка, которую я, как мне кажется, узнал. Может быть, я просто пропустил сообщения, которые ddrescue
по какой-то причине не записываются на реальное целевое устройство. Сама виртуальная машина также находилась на другом USB-накопителе, может быть, были какие-то ошибки подключения, из-за которых устройство было пропущено Live-Linux во время выполнения или что-то в этом роде. Я мог легко пропустить такие ошибки из- dmesg -T
за всех зарегистрированных ошибок чтения.
Похоже, мне придется повторить весь процесс...
решение2
Я прочитал ddrescue
руководство, и нигде не упоминается возможность использования нескольких input-position
параметров.
Этот параметр всегда упоминается как «a» или «the», поэтому, по-видимому, он должен быть уникальным.
Источником вашей проблемы может быть эта фраза из руководства:
Обратите внимание, что необходимо сохранить исходное смещение между «--input-position» и «--output-position» исходного спасательного прогона.
Это, кажется, согласуется со следующим другим абзацем:
Ddrescue не записывает нули в выходной файл, когда находит плохие сектора во входном файле, и не обрезает выходной файл, если его об этом не просят. Поэтому каждый раз, когда вы запускаете его на том же выходном файле, он пытается заполнить пробелы, не стирая уже спасенные данные.
Это означает, что он ddrescue
запоминает параметры с первого запуска, поэтому вы всегда должны сохранять те же параметры или, может быть, просто не указывать их при последующих запусках (я не могу сказать, что правильно). Вполне возможно, что некоторые параметры были запомнены, а ваши новые были проигнорированы при последующих запусках.
Если части метатаблиц диска были повреждены, вы можете увидеть меньше данных, чем было фактически восстановлено, поскольку ни один файл, по-видимому, не содержит этих частей.
Данные, которые ddrescue
невозможно спасти, необходимо восстановить с помощью других продуктов восстановления. Это может занять много времени и даже может оказаться невозможным для имеющихся в вашем распоряжении продуктов. Если данные необходимо восстановить, профессиональная компания по восстановлению может сделать это с исходного диска, но эти услуги стоят дорого.
решение3
Поскольку страница руководства ddrescue
длинная, использование ddrescue
сильно различается в зависимости от цели и уровня пользователя. В принципе, если вы используете Live Linux, вам лучше запустить его на физической машине вместо виртуальной машины, а также подключить диск к SATA без адаптера SATA/USB.
Среди других функций ddrescue
можно обойти драйвер диска ядра и буферы, следовательно, это может сократить бесполезное повторное чтение плохих кластеров. Mapfile (ранее называвшийся logfile) хранит информацию обо всех неудачных/успешных чтениях кластеров, и поэтому вы можете просто повторить аварийный шаг. Mapfile ищет ddrescue
mapfile перед тем, как начать свою работу, создает его, если он не существует, читает его, если он доступен, и начинает продолжать работу по спасению с последней записанной позиции. Вам не нужно вручную перемещать начальную позицию каждый раз, когда программа аварийно завершает работу!
Вы можете использовать различные опции, чтобы сделать процесс спасения более быстрым и безопасным. Вы также можете, и это рекомендуется, вы можете сделать процесс спасения в два или более шагов:
Первый шаг: быстро прочитайте хорошие кластеры и сразу же пропустите плохие.
Второй шаг: работа с непрочитанными кластерами из предыдущего шага и использование специальных опций для обмана функций диска (NCQ, опережающее чтение ...) в том, чтобы читать по одному сектору за раз. Соответствующие команды (я использую):
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
Если ваш диск слишком сильно нагревается или не любит слишком много операций чтения, вы можете замедлить чтение с помощью опции:--max-read-rate=50M
Это только для первого знакомства, но вы можете найти множество советов в специализированных клубах или на форумах по этому поводу ddrescue
.