Linux 磁盘管理实战指南
Linux 磁盘管理实战指南
本篇范围:磁盘管理体系——磁盘基础、RAID、分区、格式化、挂载、Swap、故障排查、特殊符号
一、磁盘基础与 RAID 阵列
在管理 Linux 磁盘之前,需要先了解磁盘的"身份证"——它是什么类型的、接口是什么、如何通过 RAID 组合多块硬盘。
1.1 核心概念
| 概念 | 定义 | 类比 |
|---|---|---|
| 内存(RAM) | 临时存放数据,断电后丢失 | 课桌桌面 |
| 磁盘 | 永久保存数据,断电不丢失 | 书柜/文件柜 |
| 磁盘接口 | 决定磁盘读写速度的通道 | 水壶的壶嘴 |
1.2 机械硬盘 vs 固态硬盘
| 类型 | 运行原理 | 转速/特点 |
|---|---|---|
| 机械硬盘(HDD) | 电机带动磁盘高速旋转,磁头读写数据 | 家用 5400/7200 rpm;企业级 10000/15000 rpm |
| 固态硬盘(SSD) | 集成电路芯片存储,无机械部件 | 速度快,无噪音 |
固态硬盘存储颗粒:SLC → MLC → TLC → 3D NAND(当前主流)
1.3 磁盘接口分类(面试常考)
| 接口 | 说明 | 应用场景 |
|---|---|---|
| SATA | 家用为主,容量大价格低 | 数据备份、家用电脑 |
| SAS | 企业级,支持热插拔 | 网站/数据库服务器 |
| PCI-E | 企业级固态专用 | 高并发高性能场景 |
| U.2 (SFF-8639) | 企业级 SSD,类似 PCI-E | 企业级存储部署 |
rpm= round per minute = 每分钟转速
1.4 企业级磁盘选型建议
| 场景 | 选型方案 |
|---|---|
| 数据备份 | SATA 硬盘,10k rpm,4TB / 8TB |
| 一般网站服务器 | SAS 接口,15k rpm,300G / 600G / 900G |
| 高并发网站 | 固态硬盘 PCI-E / SAS / SATA |
| 公有云环境 | 一般不用考虑太多(厂商已优化) |
1.5 机械硬盘内部结构(了解)
| 组成部分 | 说明 | 图片知识 |
|---|---|---|
| 盘片(Platter) | 实际存放数据的地方 | 圆形金属盘片 |
| 磁头(Head) | 贴近盘片表面,负责读写 | 极其精密,不能震动 |
| 磁道(Track) | 盘面上的圆环形区域,从0开始编号 | 同心圆 |
| 扇区(Sector) | 最小存储单位,默认 512字节 | 像披萨切片 |
| 柱面(Cylinder) | 不同盘面上相同位置的磁道组成的圆柱体 | 多层叠加 |
1.6 RAID 磁盘冗余阵列(面试高频 ⭐⭐⭐⭐⭐)
什么是 RAID?
RAID = Redundant Array of Independent Disks(独立磁盘冗余阵列)。多块硬盘通过 RAID 卡统一管理,组合使用。
三大目标(一般无法同时满足全部三点):
- 更大的容量
- 更高的性能
- 更好的冗余安全性
RAID 各级别详解与对比
┌─────────────────────────────────────────────────────────────┐
│ RAID 工作原理示意图 │
│ │
│ RAID 0 - 条带化(无冗余) │
│ ┌───┬───┬───┬───┐ │
│ │ A │ B │ C │ D │ 数据分散写入所有磁盘 │
│ └───┴───┴───┴───┘ │
│ 磁盘1 磁盘2 │
│ │
│ RAID 1 - 镜像(完全复制) │
│ ┌───────┐ ┌───────┐ │
│ │ A B C │ │ A B C │ 每块盘存完全相同的数据 │
│ └───────┘ └───────┘ │
│ 磁盘1 磁盘2 │
│ │
│ RAID 5 - 分布式校验 │
│ ┌───┬───┬───┐ │
│ │ A │ B │ P │ P=奇偶校验信息,分布到各盘 │
│ └───┴───┴───┘ 允许坏任意1块 │
│ 磁盘1 磁盘2 磁盘3 │
│ │
│ RAID 10 - 条带+镜像 │
│ ┌───────┐┌───────┐ ┌───┬───┬───┬───┐ │
│ │ A B ││ A B │ │ C │ D │ E │ F │ │
│ └───────┘└───────┘ └───┴───┴───┴───┘ │
│ 镜像对1 条带化 │
└─────────────────────────────────────────────────────────────┘
RAID 级别对比表(必背!)
| 级别 | 最少盘数 | 容量利用率 | 读性能 | 写性能 | 冗余能力 | 成本 | 典型应用 |
|---|---|---|---|---|---|---|---|
| RAID 0 | 2 | 100% | 极高 | 极高 | ❌ 无 | 低 | 临时/非关键数据 |
| RAID 1 | 2 | 50% | 高 | 中 | ✅ 允许坏1块 | 高 | 系统盘/引导分区 |
| RAID 5 | 3 | (N-1)/N | 高 | 中 | ✅ 允许坏1块 | 中 | 文件/数据存储 |
| RAID 10 | 4 | 50% | 极高 | 高 | ✅ 每组允许坏1块 | 最高 | 数据库/关键业务 |
企业实战推荐:
- 操作系统盘 → RAID 1(安全第一)
- 数据存储盘 → RAID 5(性价比均衡)
- 数据库/关键业务 → RAID 10(高性能+高可用)
1.7 物理机服务器上架与运维(了解)
如果你在公有云上操作,以下内容可以跳过。但在物理机房工作时,这些是必备常识。
服务器上架全流程
新服务器到货
↓
拆包装、检查硬件
↓
插入机柜 → 插电 → 联网
↓
开机 → 配置远程控制卡(iDrac/iLO/iBMC)
↓
配置 RAID(系统盘 RAID 1,数据盘 RAID 5)
↓
安装系统(U 盘 / PXE 网络批量部署 / cobbler)
↓
部署服务 → 上线运行
服务器分类
| 类型 | 外形 | 适用场景 |
|---|---|---|
| 机架式 | 最常见,标准宽度放入 19 寸机柜 | 数据中心主力 |
| 塔式 | 类似台式机立式外形 | 小型办公室 |
| 刀片式 | 高密度紧凑设计 | 大规模集群 |
机柜尺寸规范
| 规范项 | 说明 |
|---|---|
| 标准机柜宽度 | 19 英寸 |
| 高度单位 U | 1U = 4.45cm |
| 常见规格 | 1U、2U(最常见)、4U |
| 路数 = CPU 数量 | 2 路 = 2 颗 CPU |
更多 U 数的一般是小型机或大型机。
远程控制卡(各厂商)
当物理机网络不通或系统崩溃时,可以通过远程控制卡(独立于操作系统的管理芯片)连接排查:
| 厂商 | 远程控制卡名称 |
|---|---|
| Dell | iDrac |
| HPE(惠普) | iLO |
| IBM / Lenovo | IMM |
| 华为 | iBMC |
视频参考:老男孩 Linux 服务器上架实战
1.8 救援模式 —— 系统进不去时的最后手段
当 Linux 系统无法正常启动(忘记密码、引导损坏等),需要通过救援模式进入系统修复。
光盘救援模式 vs 单用户模式
| 对比项 | 光盘救援模式 | 单用户模式 |
|---|---|---|
| 进入方式 | U 盘/光盘启动 | 启动时修改内核参数 |
| 能否修复引导问题 | ✅ 可以(可访问磁盘) | ❌ 不行 |
| 典型用途 | 系统彻底崩溃时进入 | 重置 root 密码 |
| 复杂度 | 较复杂(需要镜像) | 较简单 |
光盘救援模式操作步骤(6 步)
# Step 1: 准备启动介质——U盘或CentOS安装光盘/ISO
# Step 2: 重启服务器,在 VMware logo 页面按 ESC 键
# 弹出启动菜单,选择从光盘/U盘启动
# Step 3: 进入 CentOS 安装页面,选择 Troubleshooting(故障排除)
# Step 4: 选择 "Rescue a CentOS system"(救援 CentOS 系统)
# Step 5: 出现提示时输入 1 选择 Continue
# 系统会将原系统挂载到 /mnt/sysimage
# Step 6: 切换根目录到原系统
chroot /mnt/sysimage # 切换后就可以像正常系统一样操作了!
# 此时可以:
# - vi /etc/passwd # 修改用户信息
# - passwd root # 重置 root 密码
# - 检查/修复配置文件
/mnt/sysimage就是你原来系统的根目录。通过 chroot 把"监狱的根"临时改成原来的位置,就能访问所有文件了。退出救援模式:输入
exit两次即可重启。
二、磁盘分区与格式化
拿到一块新磁盘后,需要经历 "打隔断 → 装修 → 安装门窗" 三部曲:分区 → 格式化 → 挂载。
2.1 磁盘分区基础
MBR 分区表结构(512 字节)
┌──────────────────────────────┬──────────┬──────────┐
│ 引导程序(MBR) │ 分区表 │ 结束标记 │
│ 446字节 │ 64字节 │ 2字节 │
│ │ 最多4个 │ 55AA │
└──────────────────────────────┴──────────┴──────────┘
| 组成 | 大小 | 说明 |
|---|---|---|
| 引导程序 | 446字节 | 系统启动引导代码 |
| 分区表(DPT) | 64字节 | 最多 4 个主分区(每个16字节) |
| 结束标记 | 2字节 | 55AA 表示 MBR 有效 |
三种分区类型
MBR 分区结构图:
主分区 + 扩展分区 ≤ 4 个(扩展分区最多1个)
├── 主分区1(/dev/sda1) ← 可直接使用
├── 主分区2(/dev/sda2) ← 可直接使用
├── 主分区3(/dev/sda3) ← 可直接使用
└── 扩展分区(/dev/sda4) ← 不能直接用!容器
├── 逻辑分区1(/dev/sda5) ← 从5开始编号,存放数据
├── 逻辑分区2(/dev/sda6)
└── 逻辑分区3(/dev/sda7)...
⚠️ MBR 限制:最多 4 个主分区;单分区最大 2TB
MBR vs GPT 对比
| 对比项 | MBR | GPT |
|---|---|---|
| 最大支持容量 | 2TB(超过不识别) | 无限制 |
| 主分区数量 | 最多 4 个 | 100+ 个 |
| 是否区分主/扩展/逻辑 | 区分 | 不区分 |
| 对应命令 | fdisk / parted | parted / gdisk |
| 兼容性 | 好(老旧系统) | 需较新系统 |
生产环境建议:小于 2TB 用 MBR+fdisk,大于 2TB 用 GPT+parted
磁盘命名规则
| 接口类型 | 前缀 | 示例 |
|---|---|---|
| SATA/SAS/SCSI | sd |
/dev/sda, /dev/sdb |
| 虚拟机/公有云 | vd |
/dev/vda, /dev/vdb |
| IDE(老旧) | hd |
/dev/hda |
命名规律:sda1 = s(SATA) + a(第1块) + 1(第1个主分区)
2.2 fdisk 命令详解 —— MBR 分区(必会!)
fdisk 是交互式 MBR 分区工具,操作流程像"菜单选择"。
fdisk 内部命令速查表
| 命令 | 功能 | 必会度 |
|---|---|---|
| m | 显示帮助/命令列表 | *** |
| p | 打印当前分区表 | ***** |
| n | 创建新分区 | ***** |
| d | 删除分区 | **** |
| t | 修改分区类型ID | ** |
| w | 保存并退出(关键!) | ***** |
| q | 退出不保存 | ***** |
实战案例:创建一个 20MB 的分区
# ===== 步骤1:查看现有磁盘 =====
fdisk -l | grep '/dev/sd'
# /dev/sda 21.5 GB ← 系统盘(已有系统)
# /dev/sdb 106 MB ← 新增的空盘,待分区
# ===== 步骤2:进入fdisk交互模式 =====
fdisk /dev/sdb # 操作目标硬盘sdb
# ===== 步骤3:交互创建分区 =====
Command (m for help): n # n = new 新建分区
Partition type: # 选择分区类型
p primary (0 primary, 0 extended, 4 free) # p=主分区
e extended # e=扩展分区
Select (default p): p # 选 p 主分区(或直接回车默认)
Partition number (1-4, default 1): # 分区号,回车默认1
First sector (2048-208895, default 2048): # 起始扇区,回车默认
Last sector, +sector or +size{K,M,G} (2048-208895): +20M
# ↑ 关键!指定大小为20M(也可以写 +20MB 或 +20K)
# ===== 步骤4:确认分区信息 =====
Command (m for help): p # p = print 打印查看
# 输出:
# Device Boot Start End Blocks Id System
# /dev/sdb1 2048 43007 20480 83 Linux ✅ 已创建!
# ===== 步骤5:保存写入 =====
Command (m for help): w # w = write 写入保存
# The partition table has been altered!
# Calling ioctl() to re-read partition table.
# ===== 步骤6:验证 =====
ls /dev/sdb* # 应该能看到 /dev/sdb1
💡 温馨提示:fdisk 中如果按退格键无法删除,试试 Ctrl+U(清整行)
2.3 parted 命令 —— GPT 分区(大硬盘必用)
parted 与 fdisk 的核心区别:parted 操作实时生效,不需要最后按 w 保存。
# ===== GPT 分区实战 =====
parted /dev/sdc # 编辑目标磁盘
(parted) mktable gpt # 先创建 GPT 分区表(或 mklabel gpt)
# 注意:MBR 在 parted 中叫 msdos
(parted) mkpart primary 0 10 # 创建第1个分区 0~10MB(实时生效!)
(parted) mkpart primary 10 20 # 创建第2个分区 10~20MB
(parted) print # 查看分区情况
(parted) rm 1 # 删除第1个分区
(parted) q # 退出
2.5 LVM 逻辑卷 —— 动态调整分区大小(了解)
LVM = Logical Volume Manager(逻辑卷管理器)
前面学的 fdisk/parted 分区,一旦划分好就固定了。LVM 的优势是:可以动态扩容/缩容。
为什么需要 LVM?
传统分区的问题:
┌──────────┬──────────┬──────────────┐
│ /boot 1G │ / 40G │ /data 100G │ ← /data 快满了怎么办?
└──────────┴──────────┴──────────────┘ 传统方案:只能新加磁盘重新规划
LVM 的解决方案:
┌─────────────────────────────────────┐
│ PV(物理卷) │
│ ┌─────────┐ ┌─────────┐ │
│ │ sdb1 │ │ sdc1 │ ← 新增硬盘 │
│ └────┬────┘ └────┬────┘ │
│ └───────┬───┘ │
│ VG(卷组)← 合并所有 PV │
│ ┌────┴────┬────┴────┐ │
│ │ LV(log) │ LV(data)│ ← 逻辑卷 │
│ └─────────┴─────────┘ │
│ /data 可以随时从 VG 中扩容! │
└─────────────────────────────────────┘
LVM 核心概念
| 概念 | 全称 | 说明 | 类比 |
|---|---|---|---|
| PV | Physical Volume(物理卷) | 真实的磁盘或分区 | 一块地皮 |
| VG | Volume Group(卷组) | 把多个 PV 合并成一个资源池 | 地产集团 |
| LV | Logical Volume(逻辑卷) | 从 VG 中划分出来的逻辑分区 | 分配给各部门的楼层 |
LVM 优缺点与建议
| 项目 | 说明 |
|---|---|
| 优点 | 在线动态扩容/缩容、快照备份、跨盘合并 |
| 缺点 | 软件实现,性能略低于直接分区;故障恢复更复杂 |
| 生产建议 | 预测未来 3-5 年的数据增长来规划容量;小公司可直接用 RAID 不用 LVM |
| 搭配使用 | RAID(硬件冗余)+ LVM(软件弹性) 是企业常见组合 |
2.4 格式化 —— 给分区"装修"
格式化 = 创建文件系统(Filesystem),分配 inode 和 block。
# 方法1:通用方式
mkfs -t xfs /dev/sdb1 # 格式化为 xfs 文件系统(CentOS 7 推荐)
mkfs -t ext4 /dev/sdb1 # 格式化为 ext4 文件系统(公有云常用)
# 方法2:专用命令(效果相同)
mkfs.xfs /dev/sdb1 # 格式化为 xfs
mkfs.ext4 /dev/sdb1 # 格式化为 ext4
# 强制覆盖已格式化的分区(加 -f 参数)
mkfs.xfs -f /dev/sdb1 # -f = force 强制
常见文件系统对比
| 文件系统 | 默认系统 | 特点 | 推荐场景 |
|---|---|---|---|
| xfs | CentOS 7 | 高性能、大文件优化 | 生产环境首选 |
| ext4 | CentOS 6 / Ubuntu | 兼容性好 | 公有云常用 |
| ext3 | CentOS 5 | 老版本 | 已淘汰 |
| swap | — | 交换分区 | 内存补充 |
三、挂载管理与 Swap 交换分区
3.1 挂载 —— 给设备装"门窗"
分区和格式化完成后,磁盘还无法使用——必须挂载到某个目录(挂载点),才能通过这个目录访问磁盘内容。
# ===== 临时挂载 =====
mount /dev/sdb1 /mnt/ # 将 sdb1 挂载到 /mnt 目录
# 验证挂载结果
df -h # 查看所有分区的使用情况
df -h | grep mnt # 过滤只看 /mnt 的挂载
# 输出: /dev/sdb1 975M 33M 943M 4% /mnt
# ===== 卸载(取消挂载)=====
umount /mnt # 通过挂载点卸载
umount /dev/sdb1 # 通过设备名卸载
# 挂载光盘/ISO
mount /dev/cdrom /media/
df -h 输出各列含义
| 列 | 含义 | 示例 |
|---|---|---|
| Filesystem | 设备名或文件系统 | /dev/sdb1 |
| Size | 总大小 | 1020M |
| Used | 已用空间 | 33M |
| Avail | 可用空间 | 988M |
| Use% | 使用率 | 4% |
| Mounted on | 挂载点目录 | /mnt |
3.2 永久挂载 —— 开机自动生效
临时挂载重启就失效了。要开机自动挂载,有两种方案:
方案一:/etc/fstab(推荐!)
fstab = filesystem table = 文件系统的"自动挂载清单"
配置格式(6 列):
| 第1列 | 第2列 | 第3列 | 第4列 | 第5列 | 第6列 |
|---|---|---|---|---|---|
| 设备名/UUID | 挂载点 | 文件系统类型 | 挂载选项 | 是否备份 | 是否检查 |
| 字段 | 说明 | 填写建议 |
|---|---|---|
| 第1列 | /dev/sdb1 或 UUID=xxx |
推荐 UUID 方式(更稳定) |
| 第2列 | 挂载目录路径 | 如 /data |
| 第3列 | 文件系统类型 | xfs / ext4 / swap |
| 第4列 | 挂载选项 | 一般填 defaults |
| 第5列 | 是否备份(dump用) | 0 = 不备份 |
| 第6列 | 是否开机检查(fsck用) | 0 = 不检查 |
配置示例:
# 使用设备名方式:
/dev/sdb1 /data xfs defaults 0 0
# 使用UUID方式(推荐!设备唯一标识):
UUID="048c0c5e-332a-44b6-bf70-99ff0c3fb2ff" /data xfs defaults 0 0
# 获取UUID的方法:
blkid /dev/sdb1 # 查看单个设备的UUID
lsblk -f # 查看所有设备及UUID(树形展示)
mount 命令 ↔ fstab 配置对照:
mount /dev/sdb1 /data→ 写入 fstab 为/dev/sdb1 /data xfs defaults 0 0
方案二:/etc/rc.local
echo 'mount /dev/sdb1 /data/' >> /etc/rc.local
chmod +x /etc/rc.d/rc.local # CentOS 7 必须先授权执行权限
3.3 磁盘使用完整流程总结(背诵版)
新磁盘上线全流程:
① fdisk /dev/sdb # 分区(MBR)或 parted(GPT)
② mkfs.xfs /dev/sdb1 # 格式化(创建文件系统)
③ mount /dev/sdb1 /data # 临时挂载验证可用
④ 编辑 /etc/fstab # 写入永久挂载配置
⑤ mount -a # 测试 fstab 配置是否正确(无报错即OK)
3.4 Swap 交换分区 —— 内存不够时的"救生圈"
什么是 Swap?
当物理内存不足时,Linux 会把一部分暂时不用的数据放到磁盘上的 swap 分区。相当于内存的"备用仓库"。
⚠️ 代价:swap 占用的是磁盘空间,速度远低于真实内存(CPU > 内存 >> 磁盘)
创建 Swap 完整步骤(4 步)
# Step 1: 用 dd 创建指定大小的空文件
dd if=/dev/zero of=/tmp/swapfile bs=1M count=1000
# if=input file(输入源) of=output file(输出目标)
# bs=block size(块大小) count=读取次数
# 总大小 = bs × count = 1MB × 1000 = 1GB ✅
# Step 2: 格式化为 swap 文件系统
mkswap /tmp/swapfile
# 转换前:data file (普通数据文件)
# 转换后:Linux/i386 swap file (swap文件)
# Step 3: 激活 swap 并设置安全权限
chmod 600 /tmp/swapfile # 安全权限(仅root可读写)
swapon /tmp/swapfile # 激活加入系统
free -h # 查看 swap 状态
# Step 4: 永久生效(写入 fstab)
/tmp/swapfile swap swap defaults 0 0
Swap 大小建议
| 物理内存 | Swap 建议 | 说明 |
|---|---|---|
| < 8GB | 内存的 1.5 ~ 2 倍 | Java应用等吃内存的场景 |
| ≥ 8GB | 8GB 即可 | 不需要太大 |
| 公有云 | 可以不配 | 云厂商已优化 |
Swap 管理
swapon -s # 查看所有 swap 设备及使用情况
swapon /tmp/swapfile # 激活 swap
swapoff /tmp/swapfile # 关闭 swap
free -h # 综合查看内存+swap
dd 命令扩展用法
# 用法1: 测试磁盘连续读写速度
dd if=/dev/zero of=/testfile bs=1M count=1000 conv=fdatasync
# conv=fdatasync = 写完后同步刷到磁盘,测的是真实磁盘速度
# 输出最后会显示: 1000MB in xx seconds → xx MB/s
# 用法2: 备份 MBR 引导扇区(512字节)
dd if=/dev/sda of=/mbr_backup.img bs=512 count=1
# if=输入源(sda) of=输出(备份文件) bs=每次读512字节 count=读1次
# 恢复时反过来:dd if=/mbr_backup.img of=/dev/sda bs=512 count=1
# 用法3: 制作一个全零的大文件(已用于创建 Swap)
dd if=/dev/zero of=/tmp/bigfile bs=1M count=500 # 创建 500MB 全零文件
⚠️ dd 被称为 "Disk Destroyer"——输出目标写错了可能覆盖重要数据,操作前务必确认
of=参数!
实战场景:Java 程序吃光内存怎么办?
现象:服务器上运行 Java 应用(如 Elasticsearch、Tomcat),大量占用内存导致系统开始使用 swap,性能急剧下降。
两步解决方案:
| 步骤 | 操作 | 说明 |
|---|---|---|
| 第一步(应急) | 增加 swap 空间 | 按上面 4 步流程快速扩 swap,先让服务不崩 |
| 第二步(根治) | 联合开发排查优化 | Java 的 -Xmx(最大堆内存)设置是否合理;是否有内存泄漏 |
参考书籍:《大话存储》—— 存储技术深入学习推荐读物,适合想深入理解底层存储原理的同学。
3.5 生产环境分区方案(实用!)
安装 Linux 系统时的分区规划直接影响后期运维。以下是三种常见场景的推荐方案:
核心原则:安装系统时手动分区,不要全自动分区!预留空间给未来的需求。
方案 A:公有云 / 数据不重要
| 分区 | 作用 | 推荐大小 |
|---|---|---|
| /boot | 引导分区,存放内核和引导文件 | 1GB |
| swap | 交换分区 | 见上方 Swap 大小建议 |
| / (根分区) | 所有剩余空间给根 | 剩余全部 |
适用场景:云主机、测试环境、数据可以随时重建
方案 B:物理机 / 私有云 / 重要数据
| 分区 | 作用 | 推荐大小 |
|---|---|---|
| /boot | 引导分区 | 1GB |
| swap | 交换分区 | 见上方建议 |
| / (根分区) | 安装软件、系统运行 | 40G ~ 200G |
| /data | 业务数据单独存放 | 剩余所有空间 |
适用场景:生产服务器、数据库、有重要业务数据的场景
为什么单独分
/data?系统崩溃重装不影响数据盘;备份更方便;权限隔离更安全。
方案 C:不确定未来用途
| 分区 | 作用 | 推荐大小 |
|---|---|---|
| /boot | 引导分区 | 1GB |
| swap | 交换分区 | 见上方建议 |
| /** (根分区) | 安装软件、系统运行 | 40G ~ 200G |
| (不划分) | 预留空间 | 剩余全部不划分! |
核心思路:谁使用谁划分。后续哪个业务需要空间就由那个负责人自己 fdisk + mkfs + mount。避免提前分好了但用不上的浪费。
四、磁盘故障排查实战(面试必备 ⭐⭐⭐⭐⭐)
磁盘空间不足是运维中最常见的故障之一。但"磁盘满了"有 3 种完全不同的原因,排查方法也各不相同。
4.1 三种磁盘空间不足故障总览
| 故障类型 | 现象 | 排查入口 | 核心命令 |
|---|---|---|---|
| Block 不足 | df -h 显示使用率 100% |
df -h → du -sh /* 逐层定位 |
du |
| Inode 耗尽 | df -h 有剩余但仍报 disk full |
df -i 查看 inode 使用率 |
df -i / find |
| 文件未彻底删除 | df -h 满了 但 du -sh 没满 |
lsof | grep delete 找残留进程 |
lsof |
4.2 故障一:Block(存储块)不足
现象:no space left on device,df -h 显示某个分区 100%。
原因:大文件/大目录占满了磁盘空间。
排查流程:
df -h ← 发现哪个分区满了
↓
du -sh /* ← 一级目录,谁占的多
↓ (比如 /var 占用最多)
du -sh /var/* ← 二级目录,继续缩小范围
↓
du -sh /var/log/* ← 三级目录,找到罪魁祸首
↓
确认 → 删除/归档/清理 ← 解决!
# 实操:逐层排查哪个目录占用最多
du -sh /* # 一级:/var 最大?
du -sh /var/* # 二级:/var/log 最大?
du -sh /var/log/* # 三级:nginx.log 2G!找到了
# 注意不要在以下虚拟目录操作:
# /sys/ /proc/ /dev/ (都是内核虚拟文件系统)
4.3 故障二:Inode 耗尽(隐蔽的"假满")
现象:
- 报错:
no space left on device - 但
df -h显示磁盘还有大量剩余空间!!!
原因:
- inode 存放文件的属性信息(权限/所有者/时间等)
- block 存放文件的实际内容
- inode 数量在格式化时就固定了
- 当系统中存在海量小文件时,inode 先于 block 被耗尽
- inode 用完了也会报 "no space left on device"
排查流程:
df -h ← 有空间?奇怪...
↓
df -i ← 看 IUse% 列!inode 用了100%?→ 就是它了
↓
find /oldboy/ -type d -size +1M ← 找包含大量小文件的目录
↓ (目录大小反映子文件数量)
find /dir -type f \| xargs dirname \| sort \| uniq -c ← 统计每个目录下文件数
↓
确认后删除/归档小文件 ← 解决!
模拟 Inode 耗尽(实验用):
dd if=/dev/zero of=/tmp/small.img bs=1M count=100 # 创建100MB小分区 mkfs.xfs /tmp/small.img; mkdir /test; mount /tmp/small.img /test cd /test && echo file{1..500000} | xargs touch # 创建50万个小文件 # 此时 df -h 还有空间,但 touch 新文件会报 no space left on device
4.4 故障三:文件未彻底删除(最棘手!)
现象:df -h 显示满了,但 du -sh / 统计出来实际占用很少。数据对不上!
文件删除原理(关键知识)
一个文件要被彻底释放磁盘空间,必须同时满足两个条件:
| 条件 | 含义 | 如何判断 |
|---|---|---|
| 条件1:硬链接数 = 0 | 已执行 rm 删除 |
ls 找不到该文件 |
| 条件2:进程调用数 = 0 | 没有任何进程在使用 | lsof | grep 文件名 无结果 |
核心考点:
rm只是把文件名删掉了(条件1满足),但如果还有进程在用这个文件(条件2不满足),磁盘空间不会释放!
lsof 命令 —— 找出"幽灵文件"
lsof = List Open Files,列出所有被进程打开的文件。
# 查找被标记为 deleted 的文件(已删除但进程还在占用的"幽灵"文件)
lsof | grep delete
# 输出示例:
# tail 15974 root 3r REG 253,1 20971520000 792978 /var/log/nginx.log (deleted)
# ↑ PID ↑ 约20GB被占着不放!
# 按服务名查找
lsof | grep nginx # 找 nginx 相关打开的文件
lsof -c nginx # 同上(更简洁写法)
# 查看某进程打开了哪些文件
lsof -p 12345 # 查看 PID=12345 的进程打开了什么
完整排查与解决流程
# Step 1: 发现异常——df满了但du不多
df -h # /dev/vda1 40G 24G 15G 63%(看起来正常?)
du -sh / # 3.9G(才3.9G?!差20G去哪了?)
# Step 2: 怀疑未彻底删除
lsof | grep delete # 找到!(deleted)标记的文件
# Step 3: 分析是谁在占用
# tail 15974 ... nginx.log (deleted)
ps -ef | grep 15974 # 是tail -f在持续读这个日志
# Step 4: 解决方案二选一
kill 15974 # 方案A:杀掉占用进程(立即释放)
systemctl restart nginx # 方案B:重启对应服务(推荐生产用)
# 验证:重启后空间应该释放了
df -h # Use% 应该降下来了 ✅
模拟故障(实验用):
seq 500000000 > big.log # 创建一个大文件
tail -f big.log & # 让tail进程持续调用它
rm -f big.log # 删除文件(此时空间不释放!)
# 此时 df-h 满了,du-sh 不满 → 用 lsof | grep delete 排查
五、特殊符号与重定向(Shell 基础进阶)
5.1 引号系列(必会!)
| 引号类型 | 特点 | 解析变量 | 解析通配符 | 典型场景 |
|---|---|---|---|---|
| 单引号 '' | 所见即所得 | ❌ 不解析 | ❌ 不解析 | 输出纯文本 |
| 双引号 "" | 解析内部变量和命令 | ✅ 解析 $() `` $变量 |
❌ 不解析 {} |
字符串拼接 |
| 不加引号 | 和双引号类似 | ✅ 全解析 | ✅ 支持 * ? |
日常命令参数 |
| 反引号 `` | 先执行里面的内容 | 命令替换 | — | 嵌入命令结果 |
# 单引号——所见即所得
echo '`hostname` $(whoami) $UID {1..5}'
# 输出: `hostname` $(whoami) $UID {1..5}
# 双引号——解析变量/命令,但不解析花括号通配符
echo "`hostname` $(whoami) $UID {1..5}"
# 输出: localhost root 0 {1..5}
# 不加引号——全部解析包括通配符
echo `hostname` $(whoami) $UID {1..5}
# 输出: localhost root 0 1 2 3 4 5
# 实用技巧:快速备份文件(花括号展开)
cp oldboy.txt{,.bak}
# 等同于: cp oldboy.txt oldboy.txt.bak
5.2 重定向符号速查表
Linux 中每个程序都有三个标准通道:
| 编号 | 名称 | 默认设备 | 说明 |
|---|---|---|---|
| 0 | stdin(标准输入) | 键盘 | 数据来源 |
| 1 | stdout(标准输出) | 屏幕 | 正确输出 |
| 2 | stderr(标准错误) | 屏幕 | 错误输出 |
重定向符号一览
| 符号 | 名称 | 含义 | 应用场景 |
|---|---|---|---|
> 或 1> |
标准输出重定向 | 清空后写入 | 覆盖写入文件 |
>> 或 1>> |
标准输出追加重定向 | 追加到末尾 | 日志追加 |
2> |
标准错误重定向 | 错误单独收集 | 单独记录报错 |
2>> |
标准错误追加重定向 | 错误追加 | 错误日志 |
>file 2>&1 |
混合重定向 | 正确+错误都写入 | 定时任务常用 |
&>file |
混合重定向(简写) | 同上 | 最简写法 ⭐ |
< |
输入重定向 | 改变输入来源 | 配合 xargs/tr |
<<EOF |
Here Document | 多行写入文件 | 写配置文件 |
# 案例1:分别收集正确和错误输出
echo ok > log.txt # 正确覆盖写入
echo error 2>> log.txt # 错误追加(eco不存在所以会报错进log.txt)
# 案例2:混合重定向——定时任务(crontab)强烈推荐
./backup.sh > backup.log 2>&1 # 写法1:容易理解
./backup.sh &> backup.log # 写法2:最简(推荐)
# 案例3:Here Document 多行写入
cat > config.conf << EOF
server_name example.com
listen 80
root /var/www/html
EOF # 结束标记必须独占一行顶格写
# 案例4:输入重定向配合 xargs 分组
xargs -n3 < num.txt # 每3行一组输出
# 1 2 3
# 4 5 6
# 7 8 9
5.3 通配符(Wildcard)
用于匹配文件名,Linux 大部分命令都支持:
| 符号 | 含义 | 示例 |
|---|---|---|
* 星号 |
匹配任意长度任意字符 | *.txt *.log *ip* |
? 问号 |
匹配单个任意字符 | ls ??(2字符文件名) |
[] |
匹配括号内一个字符 | [abc] [0-9] |
[^] |
取反,不匹配括号内 | [^abc] |
{} 花括号 |
生成序列 | {1..10} {a..z} |
花括号 {} 详细用法
# 序列生成
echo {1..10} # 1 2 3 ... 10
echo {01..10} # 01 02 ... 09 10(补零)
echo {1..10..2} # 1 3 5 7 9(步长=2,每隔2个取1个)
echo a{b,c}{1,2} # ab1 ab2 ac1 ac2(笛卡尔积)
# 枚举
echo {lidao,oldboy,zhangsan} # lidao oldboy zhangsan
# 备份神器(必学!)
cp important.txt{,.bak} # 快速备份为 .bak
# 等价于: cp important.txt important.txt.bak
echo A{,B} # A AB
5.4 正则 vs 通配符(提前了解)
| 对比维度 | 正则表达式 | 通配符(Wildcard) |
|---|---|---|
| 用途 | 匹配文件内容(字符过滤) | 匹配文件名(命令参数) |
| 支持的命令 | grep / sed / awk | ls / find / cp / mv |
| 详细学习 | 后续课程 Day22-24 | 本章 |
知识地图总结
磁盘管理知识体系
============================
┌──────────────────────┐ ┌──────────────────────┐
│ 一、磁盘基础+RAID │ │ 二、分区与格式化 │
│ HDD vs SSD │ │ MBR/GPT 对比 │
│ SATA/SAS/PCI-E │ │ fdisk 交互式分区(必会) │
│ 磁盘内部结构 │ │ parted GPT分区 │
│ RAID 0/1/5/10 │ │ LVM逻辑卷(了解) │
│ RAID对比表(面试) │ │ mkfs.xfs/mkfs.ext4 │
├──────────────────────┤ ├──────────────────────┤
│ 物理机上架流程 │ │ 生产环境分区方案 │
│ 服务器分类/尺寸规范 │ │ (公有云/物理机/预留) │
│ 远程控制卡(iDrac等) │ └──────────────────────┘
│ 救援模式(chroot) │
└──────────┬───────────┘
│
┌──────────▼───────────┐ ┌──────────────────────┐
│ 三、挂载+Swap │ │ 四、磁盘故障排查 │
│ mount/umount │ │ Block不足→du排查 │
│ fstab永久挂载 │ │ Inode耗尽→df -i │
│ dd创建Swap │ │ 未删除→lsof|delete │
│ dd扩展用法(测速) │ │ STAR法则(面试) │
│ Java内存场景案例 │ └──────────────────────┘
│ Swap大小建议 │
└──────────┬───────────┘
┌──────────▼───────────┐
│ 五、特殊符号 │
│ 引号 '' "" `` │
│ 重定向 > >> 2>&1 &> │
│ 通配符 * ? [] {} │
│ 正则引入 │
└──────────────────────┘
必背命令速查表
# ==================== 磁盘查看 ====================
lsblk # 树形列出块设备(推荐)
lsblk -f # 含 UUID(fstab用)
fdisk -l # 列出所有磁盘和分区
blkid /dev/sdb1 # 查看设备UUID
# ==================== 磁盘使用情况 ====================
df -h # 查看空间使用(human-readable)
df -i # 查看 inode 使用情况
du -sh /path # 查看目录占用空间
free -h # 查看内存 + swap
# ==================== 分区 ====================
fdisk /dev/sdb # MBR 分区(交互式:n/p/d/w/q)
parted /dev/sdc # GPT 分区(实时生效:mktable/mkpart/rm/q)
# ==================== 格式化 ====================
mkfs.xfs /dev/sdb1 # 格式化为 xfs(CentOS 7 推荐)
mkfs.ext4 /dev/sdb1 # 格式化为 ext4(公有云常用)
mkfs.xfs -f /dev/sdb1 # 强制覆盖已格式化的分区
mkswap /tmp/swapfile # 格式化为 swap
# ==================== 挂载/卸载 ====================
mount /dev/sdb1 /mnt/ # 临时挂载
umount /mnt # 卸载(通过挂载点或设备名)
mount -a # 测试 fstab 配置是否正确
# ==================== Swap 管理 ====================
swapon /tmp/swapfile # 激活 swap
swapoff /tmp/swapfile # 关闭 swap
swapon -s # 查看 swap 使用详情
# ==================== 故障排查 ====================
lsof | grep delete # 找未彻底删除的文件(幽灵文件)
lsof -c nginx # 按 服务名查找打开的文件
lsof -p PID # 按进程号查找
# ==================== 磁盘使用全流程(背诵!)===============
# ① fdisk /dev/sdb # 分区
# ② mkfs.xfs /dev/sdb1 # 格式化
# ③ mount /dev/sdb1 /data # 挂载验证
# ④ 编辑 /etc/fstab # 写入永久挂载
# ⑤ mount -a # 测试配置

浙公网安备 33010602011771号