Linux数据恢复专题——恢复丢失的分区

众荷喧哗 2011-04-16

背景
遇到“/dev/hda: device not found”这样的消息,说明你的硬盘肯定出问题了(废话-_-)!而这种消息可能是由于不同情况引起的,在这里介绍属于磁盘分区表受损时的对策。这种情况下,磁盘数据都还在,只不过暂时无法访问。

方法
鉴于仅凭记忆手工恢复分区表是不现实的,这里介绍通过软件恢复分区表:使用gpart程序扫描指定的磁盘驱动器,标识看似分区签名的表项。gpart默认只是显示像是分区的表项,但它也能将表项写入磁盘,从而重建分区表。注意,这个过程是危险的。不过总比丢失全部数据要强 :)

------------------------------------------------------------------------------------------
在你的硬盘还正常的时候,可以尝试备份分区表并存放到安全的地方,以供灾难恢复:
dd if=/dev/xxx of=filename bs=512 count=1
用于恢复的命令:
dd if=filename of=/dev/xxx bs=1 count=64 skip=446 seek=446
上面的两条命令中,xxx代表你的磁盘符号,比如hda、sda等;filename为备份文件的文件名。
注:上面的命令同时也备份了MBR和Boot Record ID,但恢复时只恢复了其中的64字节(分区表)。
------------------------------------------------------------------------------------------

gpart默认能识别下面的文件系统:beos,bsddl,ext2&ext3,fat,hpfs,hmlvm,lswap,minix,ntfs,4,rfs,s86dl和xfs。

工作
下面以/dev/hda为例:
gpart /dev/hda
上面的命令会列出gpart猜出来的分区构成,大多数情况下是和实际相符的。确认无误后,可以使用下面命令重建分区表:
gpart -W /dev/hda /dev/hda
如果不放心,可以在写前备份现有的MBR:
gpart -b filename -W /dev/hda /dev/hda
其中,filename为备份文件。

总结
磁盘主分区表损坏造成的驱动器无法识别错误,一般是比较容易解决的,gpart能够出色地猜出和重写磁盘分区表。如果是磁盘因为严重损坏而不能挂接,则可以参考本专题第二篇文章——从严重损坏的磁盘恢复数据

硬盘故障导致的数据丢失有可能是惨重的,但如果已经发生了,就需要最大程度地将数据恢复出来。本文介绍当磁盘因严重问题无法访问后(但BIOS还能识别),数据的抢救方法,并讨论ext2&ext3格式分区的磁盘短读(short read)错误。首先约定:需要手动输入的字符用黑体字给出,其余的为终端输出。

如果使用ext2或ext3文件系统,可能会收到类似下面一些警告信息,该警告信息来自e2fsck实用程序:

e2fsck /dev/hda1
e2fsck: Attempt to read block from filesystem resulted in short read

如果看到这个消息,首先想到可能是磁盘的主超级块损坏。而在创建文件系统的时候,mke2fs已经自动创建了磁盘的超级块的备份。可以告诉e2fsck程序使用一个备用超级块检查文件系统。备用超级块一般创建于块8193、16384或32768,取决于磁盘的大小(可以使用mkfs.ext3 -n /dev/hda1查看)。假设是块大硬盘,则使用:

e2fsck -b 32768 /dev/hda1

如果是超级块的问题,则程序返回后,备用超级块被启用,磁盘恢复正常。如果提示下面的问题:
e2fsck: Attempt to read block from filesystem resulted in short read while checking ext3 journal for /dev/hda1
说明问题不是出在超级块,出自日志文件系统的日志。此时可以安全地删除ext3文件系统的日志:

tune2fs -f -O ^has_journal /dev/hda1

这样就删除了/dev/hda1文件系统上的日志,这时可以重新尝试挂载分区,必要的话可以重建日志系统(使用tune2fs -j /dev/xxx)。
如果tune2fs提示下面的错误:
tune2fs: Attempt to read block from filesystem resulted in short read while reading journal inode
则说明指向日志的inode坏了,意味着无法清除日志。这时可以尝试debugfs命令,它是ext2&3文件系统的调试器。也可以再次使用e2fsck,加上-c参数检查文件系统的坏块。至此,因为无法检查或修复问题磁盘上的文件系统,该拿出杀手锏了。

使用ddrescue克隆损坏的磁盘
如果磁盘因为坏块而妨碍了读取,可以使用一个原始的磁盘复制实用程序创建磁盘的一个副本。Unix/Linux系统自带了一个简单实用程序dd,它把一个文件/分区/磁盘复制到另一个(在第一个专题里用到过)。前提条件时必须在系统里添加一块容量不小于问题磁盘的新硬盘。
新硬盘准备就绪后,输入下面命令:

dd if=/dev/hda of=/dev/hdb conv=noerror,sync

上面的命令将坏磁盘(/dev/hda)复制到新磁盘(/dev/hdb),忽略读取时遇到的错误(noerror),当遇到不能访问的块时用适当数量的空值填充输出(sync)。
但是dd有几个缺点:首先是速度太慢;然后是不显示进度信息,直到完成前它都是沉默的;不重新尝试失败的读取,这会减少能从坏盘恢复的数据量。因此在这里介绍另一个软件——ddrescue,可以从 http://www.gnu.org/software/ddrescue/ddrescue.html 获取最新版(Fedora8用户可以直接用yum install dd_rescue安装) 。目前ddrescue最新版本是1.7,直接下载链接: http://ftp.gnu.org/gnu/ddrescue/ddrescue-1.7.tar.bz2
编译、安装后,可以使用下面命令完成相同的任务:

ddrescue --max-retries=-1 /dev/hda /dev/hdb


其中max-retries=-1参数表示无论遇到多少错误都不要停止。程序从hda读取数据并写到hdb中时,不断更新各项数据,可以方便地查看工作进行情况。
在ddrescue结束磁盘复制后,在新硬盘上运行e2fsck,以消除原始磁盘的坏块引起的文件系统错误。由于肯定会有大量错误,可以用-y参数运行e2fsck,指示e2fsck对每个问题都回答yes:

e2fsck -y /dev/hdb

此时,可以使用mount命令挂载文件系统,看看数据的恢复情况了。记得检查驱动器根目录下的lost+found文件夹,fsck把不能正确链接的文件和目录放在了这个文件夹里。

相关推荐