大约 5 天前,我的 500GB 硬盘崩溃了。ddrescue
几天前,我在重要分区上使用过它,现在它已经处于“修剪失败块”状态近 2 天了。
原始命令:
ddrescue -n /dev/rdisk1s2 /Volumes/OSXBackup/rdisk1s2.img /Volumes/OSXBackup/rdisk1s2.log
电流输出:
Initial status (read from logfile)
rescued: 248992 MB, errsize: 1007 MB, errors: 15867
Current status
rescued: 249021 MB, errsize: 978 MB, current rate: 17408 B/s
ipos: 44405 MB, errors: 15866, average rate: 2784 B/s
opos: 44405 MB, time from last successful read: 0 s
Trimming failed blocks...
原始命令使用了该ddrescue -n
参数,我根据需要重新启动了该过程几次(并且每次似乎都能从中断的地方继续)。
有没有什么办法可以加快这一进程?
编辑:六个小时后,当前状态如下:
rescued: 249079 MB, errsize: 920 MB, current rate: 409 B/s
ipos: 39908 MB, errors: 15851, average rate: 2698 B/s
opos: 39908 MB, time from last successful read: 0 s
Trimming failed blocks...
看起来,虽然“错误”倒计时的速度非常缓慢,但 ipos/opos 正在倒计时它需要处理多少数据,而且它似乎以每小时 750MB 的速度运行。按照这个速度,它将在大约 53 小时内完成。哎呀。
编辑#2:两天后,仍在运行。不过,还有希望。它已经通过了“修剪失败块”部分,进入了下一阶段“拆分失败块”。如果说有什么不同的话,那就是从这个问题中应该得到的是,当涉及大量数据/错误时,这肯定需要很长时间。我唯一的希望是,当一切都尘埃落定后,我能成功恢复一些重要数据。
rescued: 249311 MB, errsize: 688 MB, current rate: 0 B/s
ipos: 26727 MB, errors: 15905, average rate: 1331 B/s
opos: 26727 MB, time from last successful read: 20 s
Splitting failed blocks...
答案1
我观察到,将-n
(不分割)选项与-r 1
(重试一次)一起使用并将-c
(集群大小)设置为较小的值会有所帮助。
我的印象是,拆分步骤非常缓慢,因为ddrescue
要拆分并再次拆分受损区域。这需要花费大量时间,因为要尝试恢复非常小的数据部分。因此,我更喜欢将(no-split) 与、、一起ddrescue
使用-n
-c 64
-c 32
-c 16
可能-n
(无分割)应该始终用于正向和反向的第一次传递。似乎数据分割得越多,克隆速度就越慢,尽管我对此不确定。我认为未处理的区域越大,再次运行时效果越好ddrescue
,因为要克隆的连续扇区越多。
由于我正在使用日志文件,因此当数据读取速度变得很低时,我会毫不犹豫地使用Ctrl+取消该命令。C
我也使用-R
(反向)模式,第一次阅读后,向后阅读的速度通常会比正向阅读的速度更快。
我不清楚再次-r N
运行命令时如何处理已重试的扇区 ( ) ddrescue
,尤其是在交替执行正向 (默认) 和反向 ( -R
) 克隆命令时。我不确定尝试的次数是否存储在日志文件中,并且可能再次执行的工作毫无用处。
可能-i
(输入位置)标志也有助于加快速度。
答案2
可能很难看到进展ddrescue
,但还有另一个命令包含在内,称为ddrescuelog
。
一个简单的命令ddrescuelog -t YourLog.txt
将输出以下有用的信息:
current pos: 2016 GB, current status: trimming
domain size: 3000 GB, in 1 area(s)
rescued: 2998 GB, in 12802 area(s) ( 99.91%)
non-tried: 0 B, in 0 area(s) ( 0%)
errsize: 2452 MB, errors: 12801 ( 0.08%)
non-trimmed: 178896 kB, in 3395 area(s) ( 0.00%)
non-split: 2262 MB, in 9803 area(s) ( 0.07%)
bad-sector: 10451 kB, in 19613 area(s) ( 0.00%)
ddrescue
您甚至可以在跑步时使用它...
答案3
我发现使用 -K 参数可以加快速度。据我所知,如果 ddrescue 在使用 -n 选项运行时发现错误,它会尝试跳过固定数量的扇区。如果它仍然无法读取,它会跳过两倍的大小。如果有大面积损坏,您可以指定一个较大的 K 值(例如 100M),这样第一次跳过错误时会更大,并且在第一次跳过时更容易快速避开有问题的区域。
顺便说一句,有一个很棒的图形应用程序可以分析日志。
答案4
监控 ddrescue 进度的另一种方法(至少在 Linux 上)是使用 strace。
首先,使用“ps aux | grep ddrescue”找到 ddrescue 进程的 PID
root@mojo:~# ps aux | grep ddrescue
root 12083 0.2 0.0 15764 3248 pts/1 D+ 17:15 0:04 ddrescue --direct -d -r0 /dev/sdb1 test.img test.logfile
root 12637 0.0 0.0 13588 940 pts/4 S+ 17:46 0:00 grep --color=auto ddrescue
然后针对该进程运行“strace”。您将看到类似以下内容的内容:
root@mojo:~# strace -p 12083
Process 12083 attached - interrupt to quit
lseek(4, 1702220261888, SEEK_SET) = 1702220261888
write(4, "\3101\316\335\213\217\323\343o\317\22M\346\325\322\331\3101\316\335\213\217\323\343o\317\22M\346\325\322\331"..., 512) = 512
lseek(3, 1702220261376, SEEK_SET) = 1702220261376
read(3, "\3101\316\335\213\217\323\343o\317\22M\346\325\322\331\3101\316\335\213\217\323\343o\317\22M\346\325\322\331"..., 512) = 512
lseek(4, 1702220261376, SEEK_SET) = 1702220261376
write(4, "\3101\316\335\213\217\323\343o\317\22M\346\325\322\331\3101\316\335\213\217\323\343o\317\22M\346\325\322\331"..., 512) = 512
^C
...等等。输出很快,但很丑陋,所以我通过“grep”将其过滤掉我关心的内容:
root@mojo:/media/u02/salvage# nice strace -p 12083 2>&1|grep lseek
lseek(4, 1702212679168, SEEK_SET) = 1702212679168
lseek(3, 1702212678656, SEEK_SET) = 1702212678656
lseek(4, 1702212678656, SEEK_SET) = 1702212678656
lseek(3, 1702212678144, SEEK_SET) = 1702212678144
lseek(4, 1702212678144, SEEK_SET) = 1702212678144
lseek(3, 1702212677632, SEEK_SET) = 1702212677632
lseek(4, 1702212677632, SEEK_SET) = 1702212677632
lseek(3, 1702212677120, SEEK_SET) = 1702212677120
lseek(4, 1702212677120, SEEK_SET) = 1702212677120
lseek(3, 1702212676608, SEEK_SET) = 1702212676608
^C
在这个例子中,“1702212676608”相当于“您试图挽救的 2 Tb 磁盘上仍需要处理的数据量。”(是的。哎哟。)ddrescue 在其屏幕输出中吐出了一个类似的数字 - 尽管是“1720 GB”。
strace 为您提供了更高粒度的数据流供您检查;这是评估 ddrescue 速度和估计完成日期的另一种方法。
持续运行它可能不是一个好主意,因为它会与 ddrescue 争夺 CPU 时间。我已将其通过管道传输到“head”,这样我就可以获取前 10 个值:
root@mojo:~# strace -p 4073 2>&1 | grep lseek | head
希望这对某人有帮助。