Linux 将硬件设备抽象为文件,磁盘也不例外。在 Linux 看来,硬盘、U盘、光驱都只是位于 /dev/ 目录下的一个文件(例如 /dev/sda)。这种设计使得操作系统可以使用统一的接口(读/写)来操作不同的硬件。
4.1 磁盘分区
磁盘分区是将物理磁盘划分为多个独立区域的过程。Linux 内核通过分区表来记录这些边界。
4.1.1 分区表类型
目前主要有两种分区表标准:
MBR(Master Boot Record)
- 传统的分区表,位于磁盘的最开始处
- 限制:最多支持 4 个主分区(或 3 个主分区 + 1 个扩展分区),最大寻址 2TB 磁盘
- 结构:包含引导代码、分区表项(4 个 16 字节的条目)和魔数
GPT(GUID Partition Table)
- 现代标准,作为 UEFI 的一部分
- 优势:支持超过 2TB 的大磁盘,支持几乎无限数量的分区(通常限制为 128 个)
- 具有 CRC 校验保证数据完整性
4.1.2 常用分区工具
| 工具名称 | 特点 | 适用场景 |
|---|---|---|
fdisk | 交互式,功能强大,不立即写入直到确认 | 创建、删除、修改分区表(推荐用于 MBR) |
parted | 命令即时生效,支持脚本化操作 | 需要脚本自动化分区,或处理 GPT 磁盘 |
gparted | parted 的图形化前端 | 桌面环境下的可视化磁盘管理 |
4.1.3 分区操作实战
使用 fdisk 修改磁盘 /dev/sdd 的典型流程:
- 启动交互:
fdisk /dev/sdd - 查看现状:输入
p打印当前分区表 - 删除旧分区:输入
d,选择分区号 - 创建新分区:输入
n,选择分区类型,设定起始扇区和大小(如+200M) - 写入磁盘:输入
w保存并退出(在此之前所有操作仅在内存中)
4.1.4 物理几何与对齐
- CHS(Cylinder-Head-Sector):早期的磁盘寻址方式。现代磁盘使用 LBA(Logical Block Addressing),将扇区线性编号
- SSD 对齐:对于固态硬盘,分区起始位置应与物理页或块对齐(通常工具默认对齐到 1MB 或 2048 扇区),否则会导致读写性能下降
4.2 文件系统基础
文件系统是内核与用户空间之间的抽象层,它将线性的块设备转化为树状的目录和文件结构。
4.2.1 常见文件系统类型
- ext4:Linux 传统默认文件系统,稳定,支持大文件,向后兼容 ext2/3
- Btrfs:现代写时复制文件系统,支持快照、压缩和动态卷管理
- XFS:高性能日志文件系统,常用于大文件服务器(如 Red Hat 默认)
- vfat/exfat:Windows FAT 系列的变种,常用于 U 盘和 SD 卡,兼容性好但无权限管理
- iso9660:光盘标准文件系统
4.2.2 创建与挂载文件系统
创建文件系统
mkfs 是一个前端工具,实际会调用具体的工具(如 mke2fs 用于 ext 系列):
mkfs -t ext4 /dev/sdf2挂载文件系统
mount -t ext4 /dev/sdf2 /home/extra
umount /home/extra # 卸载4.2.3 文件系统 UUID
设备名(如 /dev/sda1)可能因硬件变动而改变,因此推荐使用 UUID 来标识和挂载文件系统:
# 查看 UUID
blkid
# 通过 UUID 挂载
mount UUID=b600fe63-d2e9-461c-a5cd-d3b373a5e1d2 /home/extra4.2.4 /etc/fstab 配置文件
系统启动时自动挂载文件系统的配置表,每行 6 列:
UUID=... / ext4 errors=remount-ro 0 1
[设备标识] [挂载点] [文件系统类型] [选项] [dump备份] [fsck检查顺序]- dump 字段:通常设为
0(已废弃) - fsck 字段:
0= 不检查;1= 根分区(最先检查);2= 其他分区
4.2.5 文件系统检查与修复
当系统非正常关机时,文件系统元数据可能不一致,需要在下次挂载前修复:
# 交互式检查
fsck /dev/sdb1
# 自动修复
fsck -p /dev/sdb14.3 交换空间
当物理内存耗尽时,Linux 使用磁盘上的交换空间来存储不活跃的内存页。
4.3.1 交换空间类型
- 交换分区:专用的磁盘分区(类型 ID 通常为
82),性能略好,无需文件系统开销 - 交换文件:文件系统中的一个普通文件,灵活性高,无需重新分区即可调整大小
4.3.2 管理命令
# 初始化分区
mkswap /dev/sda5
# 初始化文件
dd if=/dev/zero of=/swapfile bs=1M count=100
mkswap /swapfile
# 启用/禁用
swapon /dev/sda5
swapoff /dev/sda5
# 查看状态
free -h
swapon --show4.3.3 Swap 使用策略
- 传统规则:Swap 大小 = 2 倍物理内存(适用于内存很小的旧时代)
- 现代建议:
- 桌面/休眠:需要至少等于物理内存大小的 Swap,以支持休眠功能
- 服务器:内存较大(>16GB)时,仅需少量 Swap(2GB-4GB)用于应急
- 可设置
vm.swappiness=1,告诉内核尽量避免使用 Swap,防止性能抖动
4.4 文件系统内部机制
4.4.1 Inode 结构
- Inode(索引节点):存储文件的元数据(权限、所有者、时间戳、指向数据块的指针),但不包含文件名
- 文件名:存储在目录文件的条目中,目录文件本质上是一个将文件名映射到 Inode 号的列表
4.4.2 硬链接
- 定义:多个文件名指向同一个 Inode
- 特点:删除其中一个链接,Inode 的链接计数减 1,只有当计数为 0 时,数据块才会被真正释放
- 限制:硬链接不能跨文件系统,也不能链接目录(防止循环引用)
4.4.3 块位图
文件系统使用位图来追踪数据块的使用状态:
0:块空闲1:块已占用
fsck 在检查文件系统时,会重新生成位图并与 Inode 中记录的使用情况进行比对。
4.5 文件系统日志机制
为什么现代文件系统(ext3/4、XFS、Btrfs)在断电后重启极快,而古老的 ext2 需要漫长的 fsck 检查?答案在于日志。
4.5.1 文件系统不一致的原因
当写入一个文件时,涉及多个步骤:
- 更新 Inode(元数据)
- 更新位图(标记块已占用)
- 写入实际数据块
如果在这些步骤中间断电,元数据与实际数据就会不一致。
4.5.2 日志的工作流程
日志文件系统引入”预写日志”的概念:
- 提交事务:在修改实际文件系统结构之前,先将”意图”写入日志区
- 检查点:一旦日志写入成功,系统就认为事务已提交
- 执行:按日志中的记录去修改实际的 Inode 和位图
- 清除:修改完成后,从日志中清除该记录
系统崩溃重启时,文件系统驱动只需读取日志区:
- 如果有未完成的记录,直接重做
- 如果记录已完成但标记未清除,忽略即可
4.5.3 日志模式(针对 ext4)
- Journal(数据日志):元数据和文件数据都记日志,最安全但速度最慢
- Ordered(有序模式,默认):只记元数据日志,但保证数据块先写入磁盘再提交元数据日志,兼顾安全与性能
- Writeback(回写模式):只记元数据日志,速度最快但断电后可能出现数据不一致
4.6 逻辑卷管理
LVM 在物理磁盘和文件系统之间增加了一层抽象,解决了传统分区”一旦分配难以调整”的痛点。
4.6.1 核心概念
LVM 的结构类似于”存储池”:
- PV(Physical Volume):物理卷,通常是磁盘分区(类型
8e)或整块磁盘 - VG(Volume Group):卷组,由多个 PV 组成的大池子
- LV(Logical Volume):逻辑卷,从 VG 池子中切分出来的空间,相当于”虚拟分区”
4.6.2 LVM 实战流程
1. 准备物理分区
使用 fdisk 或 parted 将磁盘分区,并将分区类型设为 Linux LVM(8e)。
2. 创建 PV 和 VG
pvcreate /dev/sdb1 /dev/sdc1
vgcreate myvg /dev/sdb1 /dev/sdc13. 创建 LV
# 从卷组 myvg 中创建一个 10GB 的逻辑卷
lvcreate --size 10g --name mylv1 myvg
# 设备路径:/dev/myvg/mylv1 或 /dev/mapper/myvg-mylv14. 使用 LV
mkfs.ext4 /dev/myvg/mylv1
mount /dev/myvg/mylv1 /mnt/data4.6.3 动态调整
LVM 的最大优势是可以在不卸载的情况下调整大小(仅限支持在线调整的文件系统):
# 扩展逻辑卷并自动调整文件系统
lvextend -r --size +100%FREE /dev/myvg/mylv14.7 设备映射器
LVM 的底层依赖于内核的设备映射器驱动。它位于物理块设备和逻辑块设备之间。
4.7.1 核心架构
dm-mod内核模块:DM 的核心驱动dmsetup工具:用户空间命令行工具,用于直接与内核的 DM 驱动交互- 目标类型:
linear:LVM 默认模式,将多个物理区域拼接成线性逻辑区域mirror:提供 RAID 1 镜像功能snapshot:提供快照功能(写时复制)crypt:提供透明加密(LUKS 的基础)
4.7.2 工作原理
- 用户空间的 LVM 工具计算好映射关系
- 通过
ioctl系统调用将映射表写入内核的/dev/mapper/control设备 - 内核空间的 Device Mapper 根据映射表,将对逻辑卷的读写请求翻译为对物理卷上具体位置的读写请求
4.7.3 多路径技术
在企业级存储环境中,服务器到存储设备通常有多条物理连接:
- 问题:操作系统会看到同一个 LUN 通过不同路径出现多次
- 解决方案:使用
device-mapper-multipath将多个路径聚合成一个虚拟设备 - 功能:故障切换(一条路径断,IO 自动切换)和负载均衡(IO 在多条路径间轮询分发)
# 查看多路径状态
multipath -ll4.8 虚拟文件系统与挂载机制
如果说文件系统是数据的存储格式,那么虚拟文件系统就是内核用来统一访问这些数据的”万能翻译官”。
4.8.1 VFS 的抽象层作用
Linux 支持几十种文件系统,应用程序不需要知道底层具体是哪种格式:
- 工作原理:VFS 定义了一组通用的接口,具体的文件系统驱动负责实现这些接口
- 流程:
用户程序→系统调用→VFS→具体文件系统驱动→块设备驱动
4.8.2 挂载的本质
挂载是将一个文件系统及其目录树附加到现有 VFS 树中某个目录的过程:
- 挂载点:被附加的目录,一旦挂载,该目录原本的内容会被”隐藏”,直到卸载
- 绑定挂载:允许将同一个文件系统或目录挂载到不同的位置
mount --bind /source/dir /target/dir
4.8.3 挂载命名空间
在现代 Linux 中,挂载不是全局唯一的:
- 不同的进程可以看到不同的挂载点列表
- 这是 Docker/容器技术的基础——容器内部看到的挂载点可能与宿主机完全不同,互不干扰
4.9 磁盘配额
当多个用户共享同一个文件系统时,管理员需要限制每个用户能使用的磁盘空间。
4.9.1 配额类型
- 块限制:限制用户能使用的磁盘空间总量
- Inode 限制:限制用户能创建的文件总数(防止耗尽 Inode)
4.9.2 软限制与硬限制
- 软限制:警告线,超过后系统会发出警告,但允许在宽限期内继续写入
- 硬限制:绝对红线,一旦达到立即禁止写入
4.9.3 管理工具
edquota:编辑用户配额repquota:报告配额使用情况quotaon/quotaoff:开启或关闭配额功能
4.10 磁盘 I/O 调度器
当多个进程同时请求读写磁盘时,内核通过 I/O 调度器决定处理顺序。
4.10.1 调度器的作用
- 合并请求:将相邻扇区的读写请求合并,减少磁头移动
- 排序:根据算法决定请求顺序
- 公平性:防止某个进程独占磁盘带宽
4.10.2 常见调度算法
| 调度器名称 | 特点 | 适用场景 |
|---|---|---|
mq-deadline | 保证请求在截止时间前完成,注重低延迟 | 适合数据库等对延迟敏感的应用 |
bfq | 基于预算的公平队列,保证每个进程获得公平带宽 | 适合桌面环境,防止界面卡顿 |
kyber | 针对多队列设备优化,简单高效 | 适合高性能 SSD |
none | 不进行调度,直接下发给硬件 | 适合自带复杂控制器的现代 NVMe SSD |
4.10.3 查看与修改
# 查看当前调度器
cat /sys/block/sda/queue/scheduler
# 临时修改
echo kyber > /sys/block/sda/queue/scheduler4.11 实战演练:综合故障排查
4.11.1 场景:磁盘空间”假性”不足
用户报告无法写入文件,提示”设备无空间”,但 df -h 显示还有剩余空间。
排查步骤:
检查块空间:
df -h # Use% 未达 100%,说明块空间未满检查 Inode 空间:
df -i # IUse% 显示 100%,说明 Inode 耗尽定位问题文件:
# 统计各目录下的文件数 find /var -xdev -type f | cut -d "/" -f 3 | sort | uniq -c | sort -nr | head清理不必要的小文件(如旧的缓存、会话文件)
4.11.2 场景:恢复误删但仍被进程占用的文件
如果文件被删除但进程仍持有句柄,空间不会立即释放:
查找被删除但仍被占用的文件:
lsof | grep deleted恢复方法(不要重启进程):
cp /proc/<PID>/fd/<FD> /tmp/recovered_file

