问题
笔者在使用dd命令构建一个可引导启动的存储介质时,使用以下命令:
do dd if=/dev/zero of=/dev/sda bs=512 count=1
将sda设备,即虚拟机硬盘的第一个扇区给格式化了,导致MBR分区表被请零,重启后文件系统崩溃,硬盘分区无法识别。
分析
首先我们要对硬盘结构有一个全面的认识,才能帮助我们了解问题的本质。
- 硬件结构
在固态硬盘还没出现之前,计算机的持久化存储设备一般是机械硬盘,再早之前就是软盘了。我们以机械硬盘为例:
这张图代表了机械硬盘的大体构造,一块机械硬盘有几个盘面就有几个磁头。
盘面上可以划分出磁道,一块盘面有多个环形磁道,每一条磁道上可以划分出多个扇区,每一个扇区存储固定大小的数据。可以看到,越靠近内侧的磁道数据密度比较大,越靠近外侧磁道数据密度比较小。
可以想象,硬盘读写有很大部分时间是在寻道上,硬盘数据读取是按照扇区读取的,这样可以增大每一次读取的数据量,从而增加磁盘的吞吐量。 - 磁盘的第一个扇区
我们在拿到磁盘之后,需要构建文件系统,不管Windows还是Linux,在磁盘格式化之后,磁盘只是一个存储设备,并不能挂载在我们的文件系统之上。
而且作为系统盘,基于x86架构的操作系统在启动的时候,主板的BIOS会默认加载启动盘的第一个扇区,到内存的0x7c00位置,然后JMP到内存的该位置
所以每一个系统盘在系统安装的时候会在磁盘的第一个扇区安装启动引导程序以及分区表。
该图片是MBR的二进制数据,白底部分为第一分区记录,由于该Ubuntu系统的系统盘只有一个分区,所以只有一项记录。
恢复思路
百度搜索大部分解决方案都是一项备份修复实验,一般没有备份MBR都无法采用,笔者也没有备份MBR,但是笔者采用了另一种笨方法。
1、 首先不能慌,不要重启系统,先用 lsblk
记录一下硬盘的分区信息,
即sda分区信息,然后关机。
2、重新按照该分区,用原镜像构建一模一样的虚拟机。如果直接关机了,那就按照记忆,重新构建镜像。
3、将原虚拟机的系统盘挂载在新创建的虚拟机下,这时使用 lsblk
显示的是一个没有分区的块设备。例如笔者显示的是sdb。
4、使用一下命令将新虚拟机MBR拷贝到原虚拟机系统盘。
sudo dd if=/dev/sda of=/dev/sdb bs=512 count=1
5、再用lsblk
命令查看硬盘是否存在分区了,然后将第二个之后的任意一个分区挂载在目录上,查看文件系统是否恢复,如果恢复了,基本没有问题。
mkdir mount_dir
mount /dev/sdb3 mount_dir
cd mount_dir
umount /dev/sdb3