一、机械硬盘结构简介
1.1、机械硬盘结构与相关概念
|--------|---------------|------------------------------------------------------------------|
| 磁盘划分为【磁头(Head)】【柱面(Cylinder)】【扇区(Sector)】 |||
| 序号 | 硬盘结构与相关概念 | 说明 |
| 1 | 磁头 | 每个磁片正反两面各有一个磁头,磁头固定在可移动的机械臂上,用于读写数据 |
| 2 | 磁道 | 当硬盘盘片旋转时,磁头若保持在一个位置上,则磁头会在盘片表面划出一个圆形轨迹,这些圆形轨迹就叫做磁道,磁道由外向内从0开始编号。 |
| 3 | 扇区 | 每个磁道上的一个弧段被成为一个扇区,它是硬盘的最小组成单元,一般扇区的大小是512字节。 |
| 4 | 柱面 | 磁片中半径相同的同心磁道(Track)构成柱面。 在实际应用中经常用到的磁盘分区就是用柱面作为范围划分的 |
| 硬盘容量:磁头数*柱面数*扇区数*512 |||
[机械硬盘的结构与相关概念]



1.2、ext4文件系统的构成
|--------|-----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 从ext2开始,磁盘分区格式化后,将【文件属性】与【文件内容】分开存储,分别由inode和block来负责。 |||
| 序号 | ext4文件系统的构成 | 说明 |
| 1 | inode | 用于存储文件的各属性(包含如下内容): 1、所有者信息:文件的owner,group; 2、权限信息:read、write和execute; 3、时间信息:建立或改变时间(ctime)、最后读取时间(atime)、最后修改时间(mtime); 4、标志信息:一些flags; 5、内容信息:type、size,以及相应的block的位置信息; 注意:inode不记录文件名或目录名,文件名或目录名记录在文件所在目录对应的block里。 inode的大小一般是128Bytes,也可能是256 Bytes。 |
| 2 | block | 用于存储文件的内容: 1、block的大小一般是1K,2K,4K,现在默认4k。 2、因为现在的磁盘都比较大,对其进行格式化后inode和block的数量非常大,为了便于管理,ext4文件系统在格式化的时候是以多个块组(block group)来进行区分和存储。 3、ext4文件系统格式化后的划分如下图所示:
|
[ext4文件系统的构成]
|--------|----------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 序号 | 块组构成 | 说明 |
| 1 | 超级块 (Superblock) | 超级块是记录整个文件系统相关信息的地方。 为了系统的健壮性,最初每个块组都有超级块和组描述符表的一个拷贝,但是当文件系统很大时,这样浪费了很多块(尤其是组描述符表占用的块多),后来采用了一种稀疏的方式来存储这些拷贝,只有块组号是3, 5 ,7的幂的块组(譬如说1,3,5,7,9,25,49...)才备份这个拷贝。通常情况下,只有主拷贝(第0块块组)的超级块信息被文件系统使用,其它拷贝只有在主拷贝被破坏的情况下才使用 |
| 2 | 块组描述符 (Filesystem Description) | 这个区段可以描述每个块组( block group )的开始与结束的块(block)号码,以及说明每个区段 (superblock, bitmap, inodemap, data block) 分别介于哪一个 block 号码之间。 |
| 3 | 区块位图 (Block Bitmap) | 区块对应表用于描述该块组所管理的块的分配状态。 如果某个块没有对应的位置位,那么代表该块未分配,可以用于存储数据;否则,代表该块已经用于存储数据或者该块不能够使用(譬如该块物理上不存在)。由于区块位图仅占一个块,因此这也就决定了块组的大小。 |
| 4 | Inode位图 (Inode Bitmap) | Inode位图用于描述该块组所管理的inode的分配状态。 我们知道inode是用于描述文件的元数据,每个inode对应文件系统中唯一的一个号,如果inode位图中存在相应位置位,那么代表该inode已经分配出去;否则可以使用。由于其仅占用一个块,因此这也限制了一个块组中所能够使用的最大inode数量。 |
| 5 | Inode表 (Inode Table) | Inode表用于存储inode信息。 它占用一个或多个块(为了有效的利用空间,多个inode存储在一个块中),其大小取决于文件系统创建时的参数,由于inode位图的限制,决定了其最大所占用的空间。 |
[block中的块组构成]
二、ext4的超级块故障模拟与恢复
2.1、模拟超级块故障
需要新添加一个磁盘,并给这个磁盘分区且挂载到/data2上后模拟超级块故障。
bash
#给新增的磁盘分区挂载
#1-查看系统当前的所有磁盘
parted -l
#2-进入新增磁盘(如:/dev/sdb)分区
#2.1-进入/dev/sdb磁盘
parted /dev/sdb
#2.2-设置磁盘的类型为gpt
mklabel gpt
#2.3-设置磁盘的分区类型与大小
mkpart primary 0gb 10gb
#2.4-保存磁盘的分区内容且退出
#3-格式化新增的磁盘分区并挂载到/data2上
mkfs.ext4 /dev/sdb1
mkdir /data2
mount /dev/sdb1 /data2
df -hT
#4-拷贝一些数据到新增磁盘的/data2挂载点上
cp -r /etc/*.conf /data2
bash
#模拟超级块故障
#1-查看指定磁盘(如:/dev/sdb1)中每个区段与superblock的信息
dumpe2fs /dev/sdb1|more
#2-使用dd命令将sdb磁盘第一个block的内容抹除
dd if=/dev/zero of=/dev/sdb1 bs=1 count=4096
#3-此时再查看指定磁盘的ext文件系统分区的超级块(superblock)信息,这些信息包含了分区的文件系统类型、创建时间、挂载次数、保留块、UUID 等关键参数会报错"tune2fs: 超级块中的幻数有错 尝试打开 /dev/sdb1 时"
tune2fs -l /dev/sdb1
mount /data2







2.2、超级块的故障恢复
超级块故障的表象,体现在:
1、使用【df -hT】命令查看时显示的磁盘大小与已用空间不正确,会显示64Z。
2、使用【tune2fs -l /dev/sda1】命令查看超级块信息时显示"tune2fs: 超级块中的幻数有错 尝试打开 /dev/sda1 时"。
3、卸载故障挂载点后重新挂载显示"mount: /data2: 文件系统类型错误、选项错误、/dev/sdb1 上有坏超级块、缺少代码页或帮助程序或其他错误.
dmesg(1) may have more information after failed mount system call."如下图所示:

bash
#恢复超级块故障的实践流程
#1-查看目前有哪些块组备份了超级块内容
#注意:如下命令的 -n 参数 ,mke2fs 并不是真的在设备上创建文件系统,它只是模拟这个过程并显示给你看。让你明白它究竟做了那些事。
mke2fs -n /dev/sdb1
#2-利用查看到的备份超级块的任意块组来进行恢复
e2fsck -b 98304 /dev/sdb1
#或者也可用如下命令开恢复【fsck.ext4 是 e2fsck 的符号链接(软链接),在绝大多数 Linux 发行版中,执行 fsck.ext4 等价于执行 e2fsck】
fsck.ext4 -b 98304 /dev/sdb1
#3-验证超级块故障是否恢复(就重新挂载这个有问题的挂载点,修复后可以正常挂载上则成功,否则失败)
mount /dev/sdb1 /data2
df -hT


到这里,恭喜你,超级块故障修复完成。
三、ext4的块组描述(GDT)故障模拟与恢复
3.1、模拟块组描述故障
块组描述符(GDT)位默认是1-4,这里直接利用dd覆盖第二个块(块号为1)
bash
#模拟块组描述符(GDT)故障
#1-卸载这个故障的挂载点
umount /data2
#2-使用dd覆盖第二个块(块号为1)【seek表示跳过】
#seek=4096,表示 跳过前 4096 个字节(bs=1,单位为字节),也就是写入 /dev/sdb1的第 4096 字节到第 8191 字节(共 4KB)的位置
dd if=/dev/zero of=/dev/sdb1 bs=1 count=4096 seek=4096

3.2、块组描述故障恢复
块组描述故障表象体现在:
1、重新挂载块描述故障提示"mount: /data2: mount(2) 系统调用失败:结构需要清理.
dmesg(1) may have more information after failed mount system call."
2、可通过【dmesg |tail -f】命令查看到"ext4_check_descriptors: Block bitmap for group 0 overlaps superblock.group descriptors corrupted!"错误。


bash
#恢复块组描述符故障实践流程
#1-直接扫描恢复指定磁盘故障分区
fsck -y /dev/sdb1
#2-验证超级块故障是否恢复(就重新挂载这个有问题的挂载点,修复后可以正常挂载上则成功,否则失败)
mount /dev/sdb1 /data2
df -hT

到这里,恭喜你,块组描述故障修复完成。