4、使用 ddrescue 进行基础恢复:安装、基本命令、从损坏磁盘创建镜像文件

好,咱们进入实战环节。

前面聊了那么多理论,说白了,都是为这一刻做准备。当你的磁盘开始咔咔响,或者系统升级到一半突然断电,再起不来的时候,你最需要的就是一个靠谱的工具。我个人最常用的,就是 ddrescue。

为什么是它?因为 dd 虽然经典,但太“耿直”了。遇到坏道,dd 直接报错退出,留下一堆烂摊子。ddrescue 不一样,它像个经验丰富的老侦探,会绕路、会重试、还会做笔记。嗯,咱们今天就把这个工具彻底搞明白。

4.1 安装 ddrescue:别装错了包

这里有个小坑,我先说一下。很多 Linux 发行版的软件源里,有两个名字很像的包:ddrescue 和 gddrescue。我刚开始用的时候也搞混过。

记住:我们要装的是 GNU 版本的 ddrescue,包名叫 gddrescue。 装完之后,可执行文件才是 ddrescue。另一个 ddrescue 包是旧版的,功能差很多,别踩坑。

发行版 安装命令 备注
Debian / Ubuntu sudo apt install gddrescue 装完用 ddrescue -V 验证
RHEL / CentOS / Rocky sudo yum install epel-release
sudo yum install ddrescue
EPEL 源里的就是 gddrescue
Fedora sudo dnf install ddrescue 直接装,没问题
Arch Linux sudo pacman -S ddrescue Arch 的包名就是 ddrescue
我的习惯:装完之后,先跑一下 ddrescue --version。看到版本号是 1.2x 以上,就对了。我曾经在 CentOS 7 上没加 EPEL 源,结果装了个古董版,折腾了半天才发现问题。

4.2 基本命令:三板斧

ddrescue 的命令格式其实不复杂。你想想看,核心就三个要素:输入文件、输出文件、日志文件。

基本语法长这样:

ddrescue [选项] /dev/源设备 /目标路径/镜像文件.dd /目标路径/恢复日志.log

我来拆解一下这三个参数:

  • 源设备:就是那块坏掉的磁盘,比如 /dev/sdb。注意,千万别写成分区(如 /dev/sdb1),除非你只想恢复那个分区。
  • 镜像文件:你要生成的镜像,通常以 .dd 或 .img 结尾。建议放在另一块健康的磁盘上,别把鸡蛋放一个篮子里。
  • 日志文件:这是 ddrescue 的灵魂。它记录了哪些块读成功了,哪些块失败了,失败了几次。有了它,你可以随时中断、续传,甚至分多次尝试不同的读取策略。
警告:日志文件必须放在健康的文件系统上。我曾经见过有人把日志文件也放在坏盘上,结果读到一半日志丢了,前功尽弃。日志文件很小,几 KB 到几 MB,别省这点空间。

4.3 从损坏磁盘创建镜像文件:实战演练

好,理论讲完了,咱们直接上手。假设我有一块 1TB 的坏盘 /dev/sdc,我要把它克隆到 /data/backup/sdc_image.dd。

4.3.1 第一轮:快速扫描,抢救好数据

第一轮的目标是“快”。先把能读的数据都读出来,坏块先跳过,不纠缠。

sudo ddrescue -f -n /dev/sdc /data/backup/sdc_image.dd /data/backup/sdc_rescue.log

解释一下参数:

  • -f:强制覆盖输出文件。如果镜像文件已存在,会覆盖它。
  • -n:不执行拆分阶段。说白了,就是遇到坏块直接跳过,不反复重试。这能极大提升第一轮的速度。

跑完之后,看看日志文件。你会看到类似这样的输出:

GNU ddrescue 1.27
Press Ctrl-C to interrupt
     ipos:   1024 GB,  non-trimed:        0 B,  current rate:  0 B/s
     opos:   1024 GB,  non-scraped:   512 MB,  average rate:  120 MB/s
non-tried:        0 B,  bad-sector:     1024,  error rate:   0 B/s
  rescued:  1023.5 GB,   busy:        0 B,  finished:  100.0%

看到 bad-sector: 1024 了吗?这说明有 1024 个坏扇区。第一轮我们成功抢救了 1023.5 GB 的数据。

4.3.2 第二轮:攻坚克难,啃硬骨头

第一轮跑完,好数据都到手了。接下来,我们要回头处理那些坏块。这一轮要慢下来,用更精细的策略去尝试读取。

sudo ddrescue -d -r 3 /dev/sdc /data/backup/sdc_image.dd /data/backup/sdc_rescue.log

新参数说明:

  • -d:直接磁盘访问。绕过操作系统缓存,直接对硬件发指令。有时候坏块在缓存层面读不出来,但硬件层面还能抢救一下。
  • -r 3:重试次数。对每个坏块,最多尝试 3 次。次数太多意义不大,反而可能把盘彻底搞死。

这一轮会很慢。512 MB 的坏块,如果盘片物理损伤严重,可能几个小时都跑不完。我的建议是:让它挂着,去做别的事。

4.3.3 第三轮(可选):终极手段,反向读取

如果第二轮之后,还有残留的坏块怎么办?别急,还有一招。

sudo ddrescue -d -R -r 1 /dev/sdc /data/backup/sdc_image.dd /data/backup/sdc_rescue.log

-R 参数表示反向读取。为什么有效?因为磁头在正向读取时,如果遇到物理划伤,可能会卡住。反向读取时,磁头从另一个方向靠近坏块,有时候就能绕过去。这招我在一块希捷的盘上成功过,救回了一个关键数据库文件。

核心思路:ddrescue 的精髓就是“分阶段、多策略”。第一轮求快,第二轮求稳,第三轮求奇。每次运行都基于同一个日志文件,它知道哪些块已经好了,哪些还需要再试。这就是它比 dd 高明的地方。

4.4 知识体系:ddrescue 恢复流程

为了让你更直观地理解整个过程,我画了一张流程图。你可以把它当成操作手册的骨架。

ddrescue 分阶段恢复流程图 开始恢复 第一轮:快速扫描 (-n) 跳过坏块,抢救好数据 有坏块? 是 第二轮:攻坚 (-d -r 3) 直接访问,重试坏块 还有残留? 是 第三轮:反向读取 (-R) 改变磁头方向,终极抢救 否 恢复完成 所有阶段共用同一个日志文件,支持随时中断和续传 最终镜像文件包含所有可恢复数据,坏块区域用零填充

4.5 避坑指南与个人经验

做这行久了,总会遇到一些奇奇怪怪的情况。我挑几个典型的说说:

  • 目标盘空间不够? 用 --size 参数限制读取大小。比如先读前 100GB:ddrescue --size=100G /dev/sdc image.dd log.log。我有个项目,坏盘 4TB,但好盘只剩 500GB,我就是这么分批救的。
  • 磁盘接口不稳定? 加 --retrim 参数。它会在所有阶段结束后,重新尝试读取之前标记为坏块但可能因为接口抖动误报的区域。说白了,就是给磁盘第二次机会。
  • 镜像文件太大,想压缩? 别直接用 ddrescue 压缩。先做完镜像,再用 gzip 或 zstd 压缩。因为 ddrescue 在恢复过程中需要随机读写日志和镜像,压缩会严重影响性能。
我曾经犯过的错:有一次,我忘了加 -f 参数,结果 ddrescue 提示输出文件已存在,直接退出了。我当时还纳闷,怎么跑不起来?后来一看,原来之前测试时生成过一个空镜像文件。所以,每次运行前,检查一下日志文件和镜像文件的状态,别让低级错误耽误时间。

好了,ddrescue 的基础用法就这些。说白了,它就是一套“先易后难、逐步攻坚”的恢复策略。你只要记住:源设备、镜像文件、日志文件这三要素,再配合 -n、-d、-r、-R 这几个核心参数,大部分磁盘损坏场景都能应付。