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 本章

在线练习地址:http://nbre.oldboylinux.cn/playground


知识地图总结

磁盘管理知识体系
============================
  ┌──────────────────────┐  ┌──────────────────────┐
  │ 一、磁盘基础+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                   # 测试配置
posted @ 2026-01-05 11:08  gzjwo  阅读(76)  评论(0)    收藏  举报